Calendar / Kalender / ميوقت (aka, the fun of locali[zs]ation) mìosachan kalendá ř رڊنيلئڪ календарь

í2 רַאדנעלַאק ປະຕiທiນ 'ISjaH

Paul Verbeek-Mast

Calendar / Kalender / ميوقت (aka, the fun of locali[zs]ation) mìosachan kalendá ř رڊنيلئڪ календарь

í2 רַאדנעלַאק ປະຕiທiນ 'ISjaH

Step 1 – implementation

http://infiniteundo.com/post/25326999628/falsehoods-programmers- believe-about-time http://infiniteundo.com/post/25509354022/more-falsehoods- programmers-believe-about-time F alsehoods programmers believe about time More f alsehoods programmers believe about time

Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 May 2017 dd-mm-yyyy Fro m dd-mm-yyyy To Price € Save

Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 May 2017 dd-mm-yyyy Fro m dd-mm-yyyy To Price € Save

Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 31 May 2017 mm-dd-yyyy Fro m mm-dd-yyyy To Price $ Save

May 2017 Fro m To Price $ Save moment . localeData (). firstDayOfWeek (); // 0-6 (Sunday to Saturday)

moment . localeData (). weekdaysMin (); //["Su", "Mo", "Tu", "We", "Th", "Fr", “ Sa"]

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

May 2017 Fro m To Price $ Save Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 31 calMoment. add ( 1 , 'd' ). date (); // 2 calMoment. isSame ( moment (). endOf ( 'month' ). endOf ( 'week' ). startOf ( 'day' ));

May 2017 Fro m To Price $ Save Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 31 ??-??-?? ??-??-?? moment . localeData ()._longDateFormat[ 'L' ]; // 'MM/DD/YYYY'

Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 31 May 2017 MM/DD/YYYY Fro m MM/DD/YYYY To Price $ Save

Step 2 – testing

RTL

Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 May 2017 dd-mm-yyyy Fro m dd-mm-yyyy To Price € Save

Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 May 2017 dd-mm-yyyy Fro m dd-mm-yyyy To Price € Save

Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 May 2017 dd-mm-yyyy Fro m dd-mm-yyyy To Price € Save

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

Step 2 – testing

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

“hate it, bring the old one back” “who made this " ? ”

“Reservations aren’t showing up” “the date selection is not working” “The prices aren’t showing properly” “All reservations are a day off” “Why are closed dates red?”

Step 3 – Bug fixing

“the date selection is not working” “Reservations aren’t showing up” “The prices aren’t showing properly” “All reservations are a day off” “Why are closed dates red?”

dd-mm-yyyy Fro m dd-mm-yyyy To

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

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

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

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

function convertToJQueryUI() { var format = moment().localeData()._longDateFormat['L'];

var dateDelimiterRegEx = /[-/]/;

var delimiter = (dateDelimiterRegEx.exec(format) || '')[0]; var dateTransform = { 'YYYY': 'yy', … 'D': 'd' }; function getTransformedDatePart(part) { return dateTransform[part] || part; } return format .split(dateDelimiterRegEx) .map(getTransformedDatePart) .join(delimiter); };

function convertToJQueryUI() { var format = moment().localeData()._longDateFormat['L'];

var dateDelimiterRegEx = /[-/]/;

var delimiter = (dateDelimiterRegEx.exec(format) || '')[0];

var dateTransform = { 
    'YYYY': 'yy', 
    … 
    'D': 'd' 
}; 
function getTransformedDatePart(part) { 
    return dateTransform[part] || part; 
} 
return format 
    .split(dateDelimiterRegEx) 
    .map(getTransformedDatePart) 
    .join(delimiter); 

};

function convertToJQueryUI() { var format = moment().localeData()._longDateFormat['L'];

var dateDelimiterRegEx = /[-/]/;

var delimiter = (dateDelimiterRegEx.exec(format) || '')[0];

var dateTransform = { 'YYYY': 'yy', … 'D': 'd' };

function getTransformedDatePart(part) { return dateTransform[part] || part; } return format .split(dateDelimiterRegEx) .map(getTransformedDatePart) .join(delimiter); };

function convertToJQueryUI() { var format = moment().localeData()._longDateFormat['L'];

var dateDelimiterRegEx = /[-/]/;

var delimiter = (dateDelimiterRegEx.exec(format) || '')[0];

var dateTransform = { 'YYYY': 'yy', … 'D': 'd' }; function getTransformedDatePart(part) { return dateTransform[part] || part; }

return format .split(dateDelimiterRegEx) .map(getTransformedDatePart) .join(delimiter); };

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

var dateDelimiterRegEx = /[-/ ]/;

var dateDelimiterRegEx = /[-/. ]/;

var dateDelimiterRegEx = /\W /;

Sloven č ina

DD. MM. YYYY var dateDelimiterRegEx = /\W /; var dateDelimiterRegEx = /\W+ /;

“Reservations aren’t showing up” “the date selection is not working” “The prices aren’t showing properly” “All reservations are a day off” “Why are closed dates red?”

Mo Tu We Th Fr Sa Su

Mo Tu We Th Fr Sa Su

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

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

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

“All reservations are a day off” “Reservations aren’t showing up” “the date selection is not working” “The prices aren’t showing properly” “Why are closed dates red?”

Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 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 May 2017 dd-mm-yyyy Fro m dd-mm-yyyy To Price € Save

“Why are closed dates red?” “Reservations aren’t showing up” “the date selection is not working” “The prices aren’t showing properly” “All reservations are a day off”

23

“The prices aren’t showing properly” “Reservations aren’t showing up” “the date selection is not working” “All reservations are a day off” “Why are closed dates red?”

23 € 125

23 Rp 1,813, 351

Conclusion

Do not make any assumptions

Localization is not just about date & time

Ask users for feedback

Save relevant data

Bugs will be there

Bugfixing =

@_paulverbeek @fronteersconf paul.verbeek@spronq .com 705649555

Questions?