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

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

Step 1 User research @paul_v_m

Step 2 Implementation @paul_v_m

@paul_v_m

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

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

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

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

@paul_v_m

date-fns js-joda @paul_v_m

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

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

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

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

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

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

Step 3 Testing @paul_v_m

RTL @paul_v_m

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

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

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

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

Step 3.1 Testing with users @paul_v_m

“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

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

“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

Step 4 Bugfixing @paul_v_m

“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

“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

Mo Tu We Th Fr Sa Su @paul_v_m

Mo Tu We Th Fr Sa Su @paul_v_m

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

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

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

“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

23 @paul_v_m

@paul_v_m

“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

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

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

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

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

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

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

Slovenčina @paul_v_m

@paul_v_m

@paul_v_m

@paul_v_m

@paul_v_m

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

“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

23 €125 @paul_v_m

23 Rp 1,813,351 @paul_v_m

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

Do not make any assumptions @paul_v_m

Localization is not just about date & time @paul_v_m

Ask your users for feedback @paul_v_m

Log any relevant data @paul_v_m

Bugfixing = # @paul_v_m

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