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
Slide 6
Calendar / Kalender /
ميوقت
(aka, the fun of locali[zs]ation)
mìosachan
kalendá
ř
رڊنيلئڪ
календарь
í2
רַאדנעלַאק
ປະຕiທiນ
'ISjaH
Slide 7
Slide 8
Step 1 – implementation
Slide 9
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 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
4
May 2017
dd-mm-yyyy
Fro m
dd-mm-yyyy
To
Price
€
Save
Slide 12
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 13
Slide 14
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 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
calMoment.
add
(
1
,
'd'
).
date
();
//
2
calMoment.
isSame
(
moment
().
endOf
(
'month'
).
endOf
(
'week'
).
startOf
(
'day'
));
Slide 17
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 18
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 19
Step 2 – testing
Slide 20
RTL
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
30
31
1
2
3
4
May 2017
dd-mm-yyyy
Fro m
dd-mm-yyyy
To
Price
€
Save
Slide 24
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 25
Step 2 – testing
Slide 26
“
❤
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 27
“hate it, bring the old one back”
“who made this
"
?
”
Slide 28
“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 29
Step 3 – Bug fixing
Slide 30
“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 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
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 41
var dateDelimiterRegEx = /[-/
]/;
Slide 42
var dateDelimiterRegEx = /[-/.
]/;
Slide 43
var dateDelimiterRegEx = /\W
/;
Slide 44
Sloven
č
ina
Slide 45
Slide 46
Slide 47
DD. MM. YYYY
var dateDelimiterRegEx = /\W
/;
var dateDelimiterRegEx = /\W+
/;
Slide 48
“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 56
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 57
“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 58
23
Slide 59
Slide 60
“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?”