Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Richard Feldman
committed
Apr 1, 2018
0 parents
commit 9db469d
Showing
3 changed files
with
207 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
elm.js | ||
# Logs | ||
logs | ||
*.log | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directory | ||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git | ||
node_modules | ||
|
||
# Elm packages and build artifacts | ||
elm-stuff |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"type": "package", | ||
"name": "rtfeldman/iso8601", | ||
"summary": "Convert ISO8601 date strings to and from Posix times", | ||
"license": "BSD-3-Clause", | ||
"version": "1.0.0", | ||
"exposed-modules": [ | ||
"Iso8601" | ||
], | ||
"elm-version": "0.19.0 <= v < 0.20.0", | ||
"dependencies": { | ||
"elm-lang/core": "6.0.0 <= v < 7.0.0", | ||
"elm-lang/parser": "1.0.0 <= v < 2.0.0", | ||
"elm-lang/time": "1.0.0 <= v < 2.0.0" | ||
}, | ||
"test-dependencies": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
module Iso8601 exposing (fromTime, toTime) | ||
|
||
import Parser exposing ((|.), (|=), Parser, int, succeed, symbol) | ||
import Time exposing (Month(..), utc) | ||
|
||
|
||
{-| Convert from an ISO-8601 date string to a Posix time. | ||
ISO-8601 date strings sometimes specify things in UTC. Other times, they specify | ||
a non-UTC time as well as a UTC offset. I view the choice to support UTC offsets | ||
as a design flaw in ISO-8601 strings. This function corrects this flaw by | ||
normalizing dates into UTC regardless of how they were specified. | ||
For example, if an ISO-8601 date string specifies "9am in UTC+2", this function | ||
will return 7am UTC. The UTC offset is automatically factored in, then discarded. | ||
-} | ||
toTime : String -> Result Parser.Error Time.Posix | ||
toTime str = | ||
Parser.run iso8601 str | ||
|
||
|
||
fromParts : Int -> Int -> Int -> Int -> Int -> Int -> Int -> Time.Posix | ||
fromParts year month day hour minute second ms = | ||
Time.millisToPosix | ||
-- TODO account for leap years | ||
((year * 365 * 24 * 60 * 60 * 1000) | ||
+ -- TODO calculate days-per-month accurately | ||
(month * 12 * 24 * 60 * 60 * 1000) | ||
+ (day * 24 * 60 * 60 * 1000) | ||
+ (hour * 60 * 60 * 1000) | ||
+ (minute * 60 * 1000) | ||
+ (second * 1000) | ||
+ ms | ||
) | ||
|
||
|
||
{-| From <https://www.timeanddate.com/date/leapyear.html> | ||
In the Gregorian calendar three criteria must be taken into account to identify leap years: | ||
- The year can be evenly divided by 4; | ||
- If the year can be evenly divided by 100, it is NOT a leap year, unless; | ||
- The year is also evenly divisible by 400. Then it is a leap year. | ||
This means that in the Gregorian calendar, the years 2000 and 2400 are leap years, while 1800, 1900, 2100, 2200, 2300 and 2500 are NOT leap years. | ||
-} | ||
isLeapYear : Int -> Bool | ||
isLeapYear year = | ||
(modBy 4 year == 0) && ((modBy 100 year /= 0) || (modBy 400 year == 0)) | ||
|
||
|
||
{-| YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ | ||
-} | ||
iso8601 : Parser Time.Posix | ||
iso8601 = | ||
-- TODO account for format variations, including those with UTC offsets | ||
succeed fromParts | ||
|= int | ||
-- YYYY | ||
|. symbol "-" | ||
|= int | ||
-- MM | ||
|. symbol "-" | ||
|= int | ||
-- DD | ||
|. symbol "T" | ||
|= int | ||
-- HH | ||
|. symbol ":" | ||
|= int | ||
-- mm | ||
|. symbol ":" | ||
|= int | ||
-- ss | ||
|. symbol ":" | ||
|= int | ||
-- sss | ||
|. symbol "Z" | ||
|
||
|
||
{-| Inflate a Posix integer into a more memory-intensive ISO-8601 date string. | ||
It's generally best to avoid doing this unless an external API requires it. | ||
(UTC integers are less error-prone, take up less memory, and are more efficient | ||
for time arithmetic.) | ||
Format: YYYY-MM-DDTHH:mm:ss.sssZ | ||
-} | ||
fromTime : Time.Posix -> String | ||
fromTime time = | ||
---- YYYY | ||
toPaddedString 4 (Time.toYear utc time) | ||
++ "-" | ||
-- MM | ||
++ fromMonth (Time.toMonth utc time) | ||
++ "-" | ||
-- DD | ||
++ toPaddedString 2 (Time.toDay utc time) | ||
++ "T" | ||
-- HH | ||
++ toPaddedString 2 (Time.toHour utc time) | ||
++ ":" | ||
-- mm | ||
++ toPaddedString 2 (Time.toMinute utc time) | ||
++ ":" | ||
-- ss | ||
++ toPaddedString 2 (Time.toSecond utc time) | ||
++ ":" | ||
-- sss | ||
++ toPaddedString 2 (Time.toMillis utc time) | ||
++ "Z" | ||
|
||
|
||
toPaddedString digits time = | ||
String.padLeft digits '0' (String.fromInt time) | ||
|
||
|
||
fromMonth : Time.Month -> String | ||
fromMonth month = | ||
case month of | ||
Jan -> | ||
"01" | ||
|
||
Feb -> | ||
"02" | ||
|
||
Mar -> | ||
"03" | ||
|
||
Apr -> | ||
"04" | ||
|
||
May -> | ||
"05" | ||
|
||
Jun -> | ||
"06" | ||
|
||
Jul -> | ||
"07" | ||
|
||
Aug -> | ||
"08" | ||
|
||
Sep -> | ||
"09" | ||
|
||
Oct -> | ||
"10" | ||
|
||
Nov -> | ||
"11" | ||
|
||
Dec -> | ||
"12" |