Calendar / Kalender /
ميوقت
(aka, the fun of locali[zs]ation)
mìosachan
kalendá
ř
رڊنيلئڪ
календарь
í2
רַאדנעלַאק
ປະຕiທiນ
'ISjaH
Slide 2
Paul Verbeek-Mast
Slide 3
Slide 4
Slide 5
Calendar / Kalender /
ميوقت
(aka, the fun of locali[zs]ation)
mìosachan
kalendá
ř
رڊنيلئڪ
календарь
í2
רַאדנעלַאק
ປະຕiທiນ
'ISjaH
Slide 6
Slide 7
Step 1 – implementation
Slide 8
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
Slide 9
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
Slide 10
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
Slide 11
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
Slide 12
Slide 13
May 2017
Fro m
To
Price
$
Save
moment
.
localeData
().
firstDayOfWeek
();
// 0-6 (Sunday to Saturday)
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
Slide 15
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'
));
Slide 16
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'
Slide 17
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
Slide 18
Step 2 – testing
Slide 19
RTL
Slide 20
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
Slide 21
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
Slide 22
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
Slide 23
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
Slide 24
Step 2 – testing
Slide 25
“
❤
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”
Slide 26
“hate it, bring the old one back”
“who made this
"
?
”
Slide 27
“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?”
Slide 28
Step 3 – Bug fixing
Slide 29
“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?”
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);
};
Slide 33
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);
};
Slide 34
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);
};
Slide 35
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);
};
Slide 36
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);
};
Slide 37
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);
};
Slide 38
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);
};
Slide 39
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);
};
Slide 40
var dateDelimiterRegEx = /[-/
]/;
Slide 41
var dateDelimiterRegEx = /[-/.
]/;
Slide 42
var dateDelimiterRegEx = /\W
/;
Slide 43
Sloven
č
ina
Slide 44
Slide 45
Slide 46
DD. MM. YYYY
var dateDelimiterRegEx = /\W
/;
var dateDelimiterRegEx = /\W+
/;
Slide 47
“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?”
“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?”
Slide 55
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
Slide 56
“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”
Slide 57
23
Slide 58
Slide 59
“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?”