Calendar / Kalender / تقويم (aka, the fun of locali[zs]ation)

A presentation at Refresh Conference in October 2018 in Groningen, Netherlands by Jayne Mast

Slide 1

Slide 1

Paul Verbeek-Mast Senior Software Engineer confrere.com @paul_v_m | noti.st/paul

Slide 2

Slide 2

kalendář ປະຕiທiນ ‫ڪئلينڊر‬ mìosachan ⽇日历 Calendar / Kalender / ‫تقويم‬ (aka, the fun of locali[zs]ation) 'ISjaH календарь ‫קאַלענדאַר‬ @paul_v_m

Slide 3

Slide 3

Step 1 User research @paul_v_m

Slide 4

Slide 4

Step 2 Implementation @paul_v_m

Slide 5

Slide 5

@paul_v_m

Slide 6

Slide 6

Falsehoods programmers believe about time http://infiniteundo.com/post/25326999628/falsehoods-programmersbelieve-about-time More falsehoods programmers believe about time http://infiniteundo.com/post/25509354022/more-falsehoodsprogrammers-believe-about-time @paul_v_m

Slide 7

Slide 7

May 2017 Mo 1 Tu 2 We 3 Th 4 Fr 5 Sa 6 Su 7 From dd-mm-yyyy To 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 dd-mm-yyyy Price € Save 29 30 31 1 2 3 4 @paul_v_m

Slide 8

Slide 8

May 2017 Mo 1 Tu 2 We 3 Th Fr 4 5 Sa 6 Su 7 From dd-mm-yyyy To 8 15 22 9 16 23 10 11 12 13 14 17 18 19 20 21 24 25 26 27 28 dd-mm-yyyy Price € Save 29 30 31 1 2 3 4 @paul_v_m

Slide 9

Slide 9

May 2017 Su 31 Mo 1 Tu 2 We 3 Th Fr 4 5 Sa 6 From mm-dd-yyyy To 7 8 14 15 21 22 9 16 23 10 11 12 13 17 18 19 20 24 25 26 27 mm-dd-yyyy Price $ Save 28 29 30 31 1 2 3 @paul_v_m

Slide 10

Slide 10

@paul_v_m

Slide 11

Slide 11

date-fns js-joda @paul_v_m

Slide 12

Slide 12

ECMAScript Temporal proposal (https://github.com/tc39/proposal-temporal) @paul_v_m

Slide 13

Slide 13

May 2017 Su Mo Tu We Th Fr Sa From To Price $ Save moment.localeData().firstDayOfWeek(); !// 0 or 1 (Sunday or Monday) moment.localeData().weekdaysMin(); !//["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"] @paul_v_m

Slide 14

Slide 14

May 2017 Su Mo Tu We Th Fr Sa From To Price $ Save var calMoment = moment(); calMoment.startOf('month').startOf('week').date(); !// 31 @paul_v_m

Slide 15

Slide 15

May 2017 Su 31 Mo Tu We 1 2 3 7 8 14 15 21 22 9 Th 4 Fr Sa 5 6 10 11 12 13 16 17 18 19 20 23 24 25 26 27 From To Price $ Save 28 29 30 31 1 2 3 var lastDay = moment().endOf('month').endOf('week').startOf('day'); !// 3 while (!calMoment.isSameOrBefore(lastDay)) { … calMoment.add(1, 'd').date(); } @paul_v_m

Slide 16

Slide 16

May 2017 Su 31 Mo Tu We 1 2 3 7 8 14 15 21 22 9 Th 4 Fr Sa 5 6 10 11 12 13 16 17 18 19 20 23 24 25 26 27 From ??-??-?? To ??-??-?? Price $ Save 28 29 30 31 1 2 3 moment.localeData()._longDateFormat['L']; !// 'MM/DD/YYYY' @paul_v_m

Slide 17

Slide 17

May 2017 Su 31 Mo 1 Tu 2 We 3 Th Fr 4 5 Sa 6 From MM/DD/YYYY To 7 8 14 15 21 22 9 16 23 10 11 12 13 17 18 19 20 24 25 26 27 MM/DD/YYYY Price $ Save 28 29 30 31 1 2 3 @paul_v_m

Slide 18

Slide 18

Step 3 Testing @paul_v_m

Slide 19

Slide 19

RTL @paul_v_m

Slide 20

Slide 20

May 2017 Mo 1 Tu 2 We 3 Th Fr 4 5 Sa 6 Su 7 From dd-mm-yyyy To 8 15 22 9 16 23 10 11 12 13 14 17 18 19 20 21 24 25 26 27 28 dd-mm-yyyy Price € Save 29 30 31 1 2 3 4 @paul_v_m

Slide 21

Slide 21

May 2017 From dd-mm-yyyy Mo 1 To dd-mm-yyyy Price € 8 Tu 2 9 We Th Fr Sa Su 3 4 5 6 7 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 1 2 3 4 Save @paul_v_m

Slide 22

Slide 22

May 2017 From dd-mm-yyyy Mo 1 To dd-mm-yyyy Price € 8 Tu 2 9 We Th Fr Sa Su 3 4 5 6 7 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 1 2 3 4 Save @paul_v_m

Slide 23

Slide 23

May 2017 From dd-mm-yyyy To dd-mm-yyyy Price € Su Sa Th We Fr Tu Mo 7 6 5 4 3 2 1 14 13 12 11 10 9 8 21 20 19 18 17 16 15 28 27 26 25 24 23 22 4 3 2 1 31 30 29 Save @paul_v_m

Slide 24

Slide 24

Step 3.1 Testing with users @paul_v_m

Slide 25

Slide 25

“much better overview” “I can finally find my reservations!” “❤ the new interface!” “Looks a lot better, just like {popular rental website for apartments}’s calendar!” @paul_v_m

Slide 26

Slide 26

“hate it, bring the old one back” “who made this 💩?” @paul_v_m

Slide 27

Slide 27

“Reservations aren’t showing up” “Why are closed dates red?” “The date selection is not working” “The prices aren’t showing properly” @paul_v_m

Slide 28

Slide 28

Step 4 Bugfixing @paul_v_m

Slide 29

Slide 29

“Reservations aren’t showing up” “Why are closed dates red?” “The date selection is not working” “The prices aren’t showing properly” @paul_v_m

Slide 30

Slide 30

“Reservations aren’t showing up” “Why are closed dates red?” “The date selection is not working” “The prices aren’t showing properly” @paul_v_m

Slide 31

Slide 31

Mo Tu We Th Fr Sa Su @paul_v_m

Slide 32

Slide 32

Mo Tu We Th Fr Sa Su @paul_v_m

Slide 33

Slide 33

Slide 34

Slide 34

https://en.wikipedia.org/wiki/Time_in_Brazil

Slide 35

Slide 35

dayA .startOf('day') .add(1, 'd') .isSame(dayB.startOf('day')); @paul_v_m

Slide 36

Slide 36

dayA .add(1, 'd') .startOf('day') .isSame(dayB.startOf('day')); @paul_v_m

Slide 37

Slide 37

“Reservations aren’t showing up” “Why are closed dates red?” “The date selection is not working” “The prices aren’t showing properly” @paul_v_m

Slide 38

Slide 38

23 @paul_v_m

Slide 39

Slide 39

@paul_v_m

Slide 40

Slide 40

“Reservations aren’t showing up” “Why are closed dates red?” “The date selection is not working” “The prices aren’t showing properly” @paul_v_m

Slide 41

Slide 41

From dd-mm-yyyy To dd-mm-yyyy @paul_v_m

Slide 42

Slide 42

05/07/2018 moment.localeData()._longDateFormat[‘L']; MM/DD/YYYY $.datepicker.parseDate('MM/DD/YYYY', ’05/07/2018'); $.datepicker.parseDate('mm/dd/yy', '05/07/2018'); @paul_v_m

Slide 43

Slide 43

function convertToJQueryUI() { const format = moment().localeData()._longDateFormat['L']; const dateDelimiterRegEx = /[-/]/; const delimiter = (dateDelimiterRegEx.exec(format) !|| ''); const dateTransform = { 'YYYY': 'yy', … 'D': 'd' } const getTransformedDatePart = part !=> dateTransform[part] !|| part; } return format .split(dateDelimiterRegEx) .map(getTransformedDatePart) .join(delimiter); @paul_v_m

Slide 44

Slide 44

const dateDelimiterRegEx = /[-/]/; 05/07/2018 05-07-2018 05.07.2018 @paul_v_m

Slide 45

Slide 45

const dateDelimiterRegEx = /[-/.]/; 05/07/2018 05-07-2018 05.07.2018 @paul_v_m

Slide 46

Slide 46

const dateDelimiterRegEx = /[\W]/; 05/07/2018 05-07-2018 05.07.2018 @paul_v_m

Slide 47

Slide 47

Slovenčina @paul_v_m

Slide 48

Slide 48

@paul_v_m

Slide 49

Slide 49

@paul_v_m

Slide 50

Slide 50

@paul_v_m

Slide 51

Slide 51

@paul_v_m

Slide 52

Slide 52

    1. 2018 const dateDelimiterRegEx = /[\W]/; const dateDelimiterRegEx = /[\W+]/; @paul_v_m

Slide 53

Slide 53

“Reservations aren’t showing up” “Why are closed dates red?” “The date selection is not working” “The prices aren’t showing properly” @paul_v_m

Slide 54

Slide 54

23 €125 @paul_v_m

Slide 55

Slide 55

23 Rp 1,813,351 @paul_v_m

Slide 56

Slide 56

Conclusion AKA. Paul tries to do some thought-leadering @paul_v_m

Slide 57

Slide 57

Do not make any assumptions @paul_v_m

Slide 58

Slide 58

Localization is not just about date & time @paul_v_m

Slide 59

Slide 59

Ask your users for feedback @paul_v_m

Slide 60

Slide 60

Log any relevant data @paul_v_m

Slide 61

Slide 61

Bugfixing = # @paul_v_m

Slide 62

Slide 62

Thank you! Paul Verbeek-Mast Senior Software Engineer confrere.com @paul_v_m | noti.st/paul