Skip to content

Commit 6170a4f

Browse files
Add new concept time and concept exercise kurokos-clock (#748)
* add concept * add exercise * add practice exercises * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Cedd Burge <[email protected]> * mention time manipulation packages in the intro * expand date format explanation * add link to elm-time-format * add introduction * bin/configlet fmt --update --------- Co-authored-by: Cedd Burge <[email protected]>
1 parent c24c6fb commit 6170a4f

File tree

16 files changed

+646
-8
lines changed

16 files changed

+646
-8
lines changed

bin/generate_concept_exercise.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ echo "Fetching latest version of configlet..."
2222
echo "Adding configuration files..."
2323
UUID=$(bin/configlet uuid)
2424
jq --arg slug "$CONCEPT_SLUG" --arg uuid "$UUID" \
25-
'.concepts += [{slug: $slug, name: "Write name from slug", uuid: $uuid }]' \
25+
'.concepts += [{uuid: $uuid, slug: $slug, name: "Write name from slug" }]' \
2626
config.json > config.json.tmp
2727
mv config.json.tmp config.json
2828

concepts/time/.meta/config.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"blurb": "Learn how to display time in Elm",
3+
"authors": [
4+
"jiegillet"
5+
],
6+
"contributors": [
7+
"ceddlyburge"
8+
]
9+
}

concepts/time/about.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# About
2+
3+
The `Time` module is used to display human-readable dates / times.
4+
While it's technically possibly to manipulate times with `Time`, there are Elm community packages that are far more suited to the task, such as [`justinmimbs/date`][date] or [`CoderDennis/elm-time-format`][elm-time-format].
5+
6+
## Posix
7+
8+
Times are represented by the opaque type `Posix`, which wraps Unix epoch time, the number of milliseconds passed since January 1st, 1970 at midnight UTC.
9+
A `Posix` is an non-ambiguous value that does not vary between time zones, therefore a good choice for keeping time.
10+
In an Elm application, `Posix` times will typically be provided by external sources, such as the browser.
11+
12+
It is possible to transform a `Posix` into a number of millisecond and vice-versa with the following functions:
13+
14+
```elm
15+
posixToMillis : Posix -> Int
16+
millisToPosix : Int -> Posix
17+
```
18+
19+
## Time Zones
20+
21+
In our day-to-day lives, we humans usually don't read `Posix` and instead prefer local time, which depends on our location on Earth, and local daylight-saving rules.
22+
In Elm, this information is encoded in the opaque type `Zone`, usually provided by the browser.
23+
24+
There is a special `Zone` that is always accessible:
25+
26+
```elm
27+
utc : Zone
28+
```
29+
30+
## Human times
31+
32+
With a `Posix` and a `Zone`, we have enough information to show local time in any level of details.
33+
Here is a list of the functions that can be used for that:
34+
35+
```elm
36+
toYear : Zone -> Posix -> Int
37+
toMonth : Zone -> Posix -> Month
38+
toDay : Zone -> Posix -> Int
39+
toWeekday : Zone -> Posix -> Weekday
40+
toHour : Zone -> Posix -> Int
41+
toMinute : Zone -> Posix -> Int
42+
toSecond : Zone -> Posix -> Int
43+
toMillis : Zone -> Posix -> Int
44+
```
45+
46+
You will have spotted two more `Time` custom types:
47+
48+
```elm
49+
type Month = Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
50+
type Weekday = Mon | Tue | Wed | Thu | Fri | Sat | Sun
51+
```
52+
53+
It is left to users to convert these custom types to human-readable values.
54+
55+
[date]: https://package.elm-lang.org/packages/justinmimbs/date/latest
56+
[elm-time-format]: https://package.elm-lang.org/packages/CoderDennis/elm-time-format/latest

concepts/time/introduction.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Introduction
2+
3+
The `Time` module is used to display human-readable dates / times.
4+
While it's technically possibly to manipulate times with `Time`, there are Elm community packages that are far more suited to the task, such as [`justinmimbs/date`][date] or [`CoderDennis/elm-time-format`][elm-time-format].
5+
6+
## Posix
7+
8+
Times are represented by the opaque type `Posix`, which wraps Unix epoch time, the number of milliseconds passed since January 1st, 1970 at midnight UTC.
9+
A `Posix` is an non-ambiguous value that does not vary between time zones, therefore a good choice for keeping time.
10+
In an Elm application, `Posix` times will typically be provided by external sources, such as the browser.
11+
12+
It is possible to transform a `Posix` into a number of millisecond and vice-versa with the following functions:
13+
14+
```elm
15+
posixToMillis : Posix -> Int
16+
millisToPosix : Int -> Posix
17+
```
18+
19+
## Time Zones
20+
21+
In our day-to-day lives, we humans usually don't read `Posix` and instead prefer local time, which depends on our location on Earth, and local daylight-saving rules.
22+
In Elm, this information is encoded in the opaque type `Zone`, usually provided by the browser.
23+
24+
There is a special `Zone` that is always accessible:
25+
26+
```elm
27+
utc : Zone
28+
```
29+
30+
## Human times
31+
32+
With a `Posix` and a `Zone`, we have enough information to show local time in any level of details.
33+
Here is a list of the functions that can be used for that:
34+
35+
```elm
36+
toYear : Zone -> Posix -> Int
37+
toMonth : Zone -> Posix -> Month
38+
toDay : Zone -> Posix -> Int
39+
toWeekday : Zone -> Posix -> Weekday
40+
toHour : Zone -> Posix -> Int
41+
toMinute : Zone -> Posix -> Int
42+
toSecond : Zone -> Posix -> Int
43+
toMillis : Zone -> Posix -> Int
44+
```
45+
46+
You will have spotted two more `Time` custom types:
47+
48+
```elm
49+
type Month = Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
50+
type Weekday = Mon | Tue | Wed | Thu | Fri | Sat | Sun
51+
```
52+
53+
It is left to users to convert these custom types to human-readable values.
54+
55+
[date]: https://package.elm-lang.org/packages/justinmimbs/date/latest
56+
[elm-time-format]: https://package.elm-lang.org/packages/CoderDennis/elm-time-format/latest

concepts/time/links.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[
2+
{
3+
"url": "https://guide.elm-lang.org/effects/time",
4+
"description": "Official guide about using time in an Elm application"
5+
},
6+
{
7+
"url": "https://package.elm-lang.org/packages/elm/time/latest/",
8+
"description": "Documentation of the Time module"
9+
},
10+
{
11+
"url": "https://package.elm-lang.org/packages/justinmimbs/date/latest/",
12+
"description": "Community package for working with dates without times or zones."
13+
},
14+
{
15+
"url": "https://package.elm-lang.org/packages/waratuman/time-extra/latest/",
16+
"description": "Community package for manipulating Posix types."
17+
},
18+
{
19+
"url": "https://package.elm-lang.org/packages/CoderDennis/elm-time-format/latest/",
20+
"description": "Community package for formatting dates and times with support for internationalization."
21+
},
22+
{
23+
"url": "https://package.elm-lang.org/packages/rtfeldman/elm-iso8601-date-strings/latest/",
24+
"description": "Community package for parsing and rendering ISO-8601 date strings."
25+
}
26+
]

config.json

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,20 @@
388388
"pattern-matching"
389389
],
390390
"status": "beta"
391+
},
392+
{
393+
"slug": "kurokos-clock",
394+
"name": "Kuroko's Clock",
395+
"uuid": "5fd8037b-df05-4e14-90e1-70f52487d14c",
396+
"concepts": [
397+
"time"
398+
],
399+
"prerequisites": [
400+
"strings",
401+
"custom-types",
402+
"pattern-matching"
403+
],
404+
"status": "beta"
391405
}
392406
],
393407
"practice": [
@@ -1031,16 +1045,14 @@
10311045
"name": "Gigasecond",
10321046
"uuid": "5ddfed31-b787-48f9-b3bf-4a8d157d1c3d",
10331047
"practices": [
1034-
"basics-1"
1048+
"time"
10351049
],
10361050
"prerequisites": [
10371051
"basics-1",
1038-
"basics-2"
1052+
"basics-2",
1053+
"time"
10391054
],
1040-
"difficulty": 1,
1041-
"topics": [
1042-
"dates"
1043-
]
1055+
"difficulty": 1
10441056
},
10451057
{
10461058
"slug": "rna-transcription",
@@ -1534,8 +1546,11 @@
15341546
"slug": "swift-scheduling",
15351547
"name": "Swift Scheduling",
15361548
"uuid": "d0438147-3983-47bf-a4db-27fb0f5ae90e",
1537-
"practices": [],
1549+
"practices": [
1550+
"time"
1551+
],
15381552
"prerequisites": [
1553+
"time",
15391554
"strings",
15401555
"records",
15411556
"custom-types",
@@ -1675,6 +1690,11 @@
16751690
"uuid": "afb8dec3-c776-4f46-a6ee-77d30963cf56",
16761691
"slug": "json",
16771692
"name": "JSON"
1693+
},
1694+
{
1695+
"uuid": "9dbfbc83-7e02-4ab4-867a-52ecd2276566",
1696+
"slug": "time",
1697+
"name": "Time"
16781698
}
16791699
],
16801700
"key_features": [
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Hints
2+
3+
## General
4+
5+
- Check out the [`elm/time` documentation][elm-time] for working with dates and times
6+
- The introduction showcases most of the necessary concepts to solve the exercise
7+
8+
## 1. It's a date
9+
10+
- The [`String.fromInt` function][fromInt] can convert numbers to strings
11+
- You'll need to convert months to their numeric representation, consider creating a helper function
12+
- For the Japanese locale, you can copy paste the characters from the instructions (年, 月, 日), the numbers should not be formatted in a Japanese encoding
13+
14+
## 2. It's show time
15+
16+
- The [`modBy` function][modBy] can help with hour conversion
17+
- Use [`String.padLeft`][padLeft] to ensure minutes have leading zeros
18+
- For the Japanese locale, you can copy paste the characters from the instructions (時, 分), the numbers should not be formatted in a Japanese encoding
19+
20+
## 3. Get in the zone
21+
22+
- [`Time.toYear`][toYear], [`Time.toMonth`][toMonth], [`Time.toDay`][toDay] can help get date parts
23+
- [`Time.toHour`][toHour] and [`Time.toMinute`][toMinute] can help get time parts
24+
- Combine the results from `showLocalDate` and `showLocalTime`
25+
26+
[elm-time]: https://package.elm-lang.org/packages/elm/time/latest/
27+
[fromInt]: https://package.elm-lang.org/packages/elm/core/latest/String#fromInt
28+
[modBy]: https://package.elm-lang.org/packages/elm/core/latest/Basics#modBy
29+
[padLeft]: https://package.elm-lang.org/packages/elm/core/latest/String#padLeft
30+
[toYear]: https://package.elm-lang.org/packages/elm/time/latest/Time#toYear
31+
[toMonth]: https://package.elm-lang.org/packages/elm/time/latest/Time#toMonth
32+
[toDay]: https://package.elm-lang.org/packages/elm/time/latest/Time#toDay
33+
[toHour]: https://package.elm-lang.org/packages/elm/time/latest/Time#toHour
34+
[toMinute]: https://package.elm-lang.org/packages/elm/time/latest/Time#toMinute
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Instructions
2+
3+
Your Japanese friend Kuroko is a streamer with an international appeal.
4+
Kuroko's streaming schedule is pretty intricate, each stream seemingly starts at a different time every day.
5+
6+
He asks for your help in building a small application that will display his schedule in his viewers' local time zones: Kuroko's Clock.
7+
He has an additional requirement: the app should be able to display the time in two different languages: Japanese and US English.
8+
9+
## 1. It's a date
10+
11+
Define a function `showLocalDate : Locale -> Int -> Month -> Int -> String` which will display a (valid) local date.
12+
13+
In the `US` locale, the format will be `Month/Day/Year` without leading zeroes.
14+
15+
In the `JP` locale, the format will be `Year年Month月Day日`, also without leading zeroes.
16+
17+
```elm
18+
showLocalDate US 2025 May 1
19+
-- "5/1/2025"
20+
showLocalDate JP 2025 May 1
21+
-- "2025年5月1日"
22+
```
23+
24+
## 2. It's show time
25+
26+
Define a function `showLocalTime : Locale -> Int -> Int -> String` which will display a (valid) local time.
27+
28+
In the `US` locale, the hours will be shown in 12-hour notation along with "PM" or "AM", and the minutes will be shown with leading zeros.
29+
30+
In the `JP` locale, the hour will be shown in 24-hour notation before "時" and the minutes will be shown without leading zeros before "分".
31+
32+
```elm
33+
showLocalTime US 13 8
34+
-- "1:08 PM"
35+
showLocalTime JP 13 8
36+
-- "13時8分"
37+
```
38+
39+
## 3. Get in the zone
40+
41+
Define a function `showDateTime : Locale -> Zone -> Posix -> String` which will display a date and time relative to a time zone in a specific locale.
42+
43+
Use `showLocalDate` and `showLocalTime` to display the final result.
44+
45+
```elm
46+
showDateTime US Time.utc (Time.millisToPosix 0)
47+
-- "1/1/1970 12:00 AM"
48+
showDateTime JP Time.utc (Time.millisToPosix 0)
49+
-- "1970年1月1日0時0分"
50+
```
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Introduction
2+
3+
## Time
4+
5+
The `Time` module is used to display human-readable dates / times.
6+
While it's technically possibly to manipulate times with `Time`, there are Elm community packages that are far more suited to the task, such as [`justinmimbs/date`][date] or [`CoderDennis/elm-time-format`][elm-time-format].
7+
8+
### Posix
9+
10+
Times are represented by the opaque type `Posix`, which wraps Unix epoch time, the number of milliseconds passed since January 1st, 1970 at midnight UTC.
11+
A `Posix` is an non-ambiguous value that does not vary between time zones, therefore a good choice for keeping time.
12+
In an Elm application, `Posix` times will typically be provided by external sources, such as the browser.
13+
14+
It is possible to transform a `Posix` into a number of millisecond and vice-versa with the following functions:
15+
16+
```elm
17+
posixToMillis : Posix -> Int
18+
millisToPosix : Int -> Posix
19+
```
20+
21+
### Time Zones
22+
23+
In our day-to-day lives, we humans usually don't read `Posix` and instead prefer local time, which depends on our location on Earth, and local daylight-saving rules.
24+
In Elm, this information is encoded in the opaque type `Zone`, usually provided by the browser.
25+
26+
There is a special `Zone` that is always accessible:
27+
28+
```elm
29+
utc : Zone
30+
```
31+
32+
### Human times
33+
34+
With a `Posix` and a `Zone`, we have enough information to show local time in any level of details.
35+
Here is a list of the functions that can be used for that:
36+
37+
```elm
38+
toYear : Zone -> Posix -> Int
39+
toMonth : Zone -> Posix -> Month
40+
toDay : Zone -> Posix -> Int
41+
toWeekday : Zone -> Posix -> Weekday
42+
toHour : Zone -> Posix -> Int
43+
toMinute : Zone -> Posix -> Int
44+
toSecond : Zone -> Posix -> Int
45+
toMillis : Zone -> Posix -> Int
46+
```
47+
48+
You will have spotted two more `Time` custom types:
49+
50+
```elm
51+
type Month = Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
52+
type Weekday = Mon | Tue | Wed | Thu | Fri | Sat | Sun
53+
```
54+
55+
It is left to users to convert these custom types to human-readable values.
56+
57+
[date]: https://package.elm-lang.org/packages/justinmimbs/date/latest
58+
[elm-time-format]: https://package.elm-lang.org/packages/CoderDennis/elm-time-format/latest
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Introduction
2+
3+
%{concept: time}

0 commit comments

Comments
 (0)