local_time 2.1.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <meta charset="utf-8">
4
+ <title>Test Suite</title>
5
+ <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.19.4.css">
6
+ </head>
7
+ <body>
8
+ <div id="qunit"></div>
9
+ <div id="qunit-fixture"></div>
10
+
11
+ <script src="https://code.jquery.com/qunit/qunit-2.19.4.js"></script>
12
+ <script src="/test-build"></script>
13
+
14
+ <time id="one" data-format="%B %e, %Y %l:%M%P" data-local="time" datetime="2013-11-12T12:13:00Z"></time>
15
+ <time id="two" data-format="%B %e, %Y %l:%M%P" data-local="time" datetime="2013-01-02T02:04:00Z"></time>
16
+ <time id="past" data-format="%B %e, %Y %l:%M%P" data-local="time" datetime="1805-05-15T01:01:00Z"></time>
17
+ <time id="future" data-format="%B %e, %Y %l:%M%P" data-local="time" datetime="3333-02-14T23:55:00Z"></time>
18
+ <time id="date" data-format="%B %e, %Y" data-local="time" datetime="2013-11-12T12:13:00Z"></time>
19
+ <time id="ago"></time>
20
+ </body>
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <meta charset="utf-8">
4
+ <title>Time Zone Check</title>
5
+ <script src="/current-build"></script>
6
+ </head>
7
+ <body>
8
+ <script>
9
+ LocalTime.start()
10
+ </script>
11
+
12
+ <p><strong>Standard Time (Northern Hemisphere) | DST Time (Southern Hemisphere)</strong></p>
13
+ <time data-format="%B %e, %Y %l:%M%P (%Z)" data-local="time" datetime="2023-12-12T12:13:00Z"></time>
14
+
15
+ <br>
16
+ <br>
17
+
18
+ <p><strong>DST Time (Northern Hemisphere) | Standard Time (Southern Hemisphere)</strong></p>
19
+ <time data-format="%B %e, %Y %l:%M%P (%Z)" data-local="time" datetime="2023-07-12T12:13:00Z"></time>
20
+ </body>
@@ -0,0 +1,41 @@
1
+ import { Router } from "express"
2
+ import express from "express"
3
+ import path from "path"
4
+ import * as url from 'url'
5
+
6
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
7
+ const router = Router()
8
+
9
+ router.get("/", (_request, response) => {
10
+ const fixture = path.join(__dirname, "./fixtures/index.html")
11
+ response.status(200).sendFile(fixture)
12
+ })
13
+
14
+ router.get("/time-zone-check", (_request, response) => {
15
+ const fixture = path.join(__dirname, "./fixtures/time_zone_check.html")
16
+ response.status(200).sendFile(fixture)
17
+ })
18
+
19
+ router.get("/test-build", (_request, response) => {
20
+ const file = path.join(__dirname, "./builds/index.js")
21
+ response.status(200).sendFile(file)
22
+ })
23
+
24
+ router.get("/current-build", (_request, response) => {
25
+ const file = path.join(__dirname, "./../../app/assets/javascripts/local-time.es2017-umd.js")
26
+ response.status(200).sendFile(file)
27
+ })
28
+
29
+ const app = express()
30
+ app.use(express.static("."))
31
+ app.use(router)
32
+
33
+ const port = parseInt(process.env.PORT || "9000")
34
+ app.listen(port, () => {
35
+ console.log(`
36
+ /*
37
+ Please go to http://localhost:${port}/ to run JS tests now.
38
+ Or go to http://localhost:${port}/time-zone-check to manually test a time zone.
39
+ */
40
+ `)
41
+ })
@@ -0,0 +1,94 @@
1
+ import LocalTime from "local_time"
2
+
3
+ {addTimeEl, assert, defer, getText, testAsync, testGroup, getTitle} = LocalTime.TestHelpers
4
+ {config} = LocalTime
5
+
6
+ testGroup "format24 (24h time)", ->
7
+ testAsync "default behavior", (done) ->
8
+ now = moment()
9
+
10
+ el = addTimeEl format: "%-l:%M%P", format24: "%H:%M", datetime: now.toISOString()
11
+ defer ->
12
+ assert.equal getText(el), now.format("h:mma")
13
+ done()
14
+
15
+ testAsync "turned off", (done) ->
16
+ now = moment()
17
+ originalFormat24 = config.useFormat24
18
+ config.useFormat24 = false
19
+
20
+ el = addTimeEl format: "%-l:%M%P", format24: "%H:%M", datetime: now.toISOString()
21
+ defer ->
22
+ assert.equal getText(el), now.format("h:mma")
23
+ config.useFormat24 = originalFormat24
24
+ done()
25
+
26
+ testAsync "turned on", (done) ->
27
+ now = moment()
28
+ originalFormat24 = config.useFormat24
29
+ config.useFormat24 = true
30
+
31
+ el = addTimeEl format: "%-l:%M%P", format24: "%H:%M", datetime: now.toISOString()
32
+ defer ->
33
+ assert.equal getText(el), now.format("HH:mm")
34
+ config.useFormat24 = originalFormat24
35
+ done()
36
+
37
+ testAsync "fallback for missing data-format24 values", (done) ->
38
+ now = moment()
39
+ originalFormat24 = config.useFormat24
40
+ config.useFormat24 = true
41
+
42
+ el = addTimeEl format: "%-l:%M%P", datetime: now.toISOString()
43
+ defer ->
44
+ assert.equal getText(el), now.format("h:mma")
45
+ config.useFormat24 = originalFormat24
46
+ done()
47
+
48
+ testAsync "turned off for relative time elements", (done) ->
49
+ ago = moment().subtract("days", 5)
50
+ originalFormat24 = config.useFormat24
51
+ config.useFormat24 = false
52
+
53
+ el = addTimeEl type: "time-ago", datetime: ago.toISOString()
54
+ defer ->
55
+ assert.equal getText(el), "#{ago.format("dddd")} at #{ago.format("h:mma")}"
56
+ config.useFormat24 = originalFormat24
57
+ done()
58
+
59
+ testAsync "turned on for relative time elements", (done) ->
60
+ ago = moment().subtract("days", 5)
61
+ originalFormat24 = config.useFormat24
62
+ config.useFormat24 = true
63
+
64
+ el = addTimeEl type: "time-ago", datetime: ago.toISOString()
65
+ defer ->
66
+ assert.equal getText(el), "#{ago.format("dddd")} at #{ago.format("HH:mm")}"
67
+ config.useFormat24 = originalFormat24
68
+ done()
69
+
70
+ testAsync "element title when turned off", (done) ->
71
+ ago = moment().subtract("days", 5)
72
+ originalFormat24 = config.useFormat24
73
+ config.useFormat24 = false
74
+
75
+ el = addTimeEl type: "time-ago", datetime: ago.toISOString()
76
+ defer ->
77
+ regex = new RegExp(ago.format('MMMM D, YYYY [at] h:mma') + " (\\w{3,4}|UTC[+-]d+)")
78
+ assert.ok regex.test(getTitle(el)), "'#{getTitle(el)}' doesn't look correct, it should match regex #{regex}"
79
+ config.useFormat24 = originalFormat24
80
+ done()
81
+
82
+
83
+ testAsync "element title when turned on", (done) ->
84
+ ago = moment().subtract("days", 5)
85
+ originalFormat24 = config.useFormat24
86
+ config.useFormat24 = true
87
+
88
+ el = addTimeEl type: "time-ago", datetime: ago.toISOString()
89
+ defer ->
90
+ regex = new RegExp(ago.format('MMMM D, YYYY [at] HH:mm') + " (\\w{3,4}|UTC[+-]d+)")
91
+ assert.ok regex.test(getTitle(el)), "'#{getTitle(el)}' doesn't look correct, it should match regex #{regex}"
92
+ config.useFormat24 = originalFormat24
93
+ done()
94
+
@@ -1,3 +1,5 @@
1
+ import LocalTime from "local_time"
2
+
1
3
  {addTimeEl, assert, defer, getText, setText, test, testAsync, testGroup, triggerEvent} = LocalTime.TestHelpers
2
4
  {config} = LocalTime
3
5
  {i18n} = config
@@ -0,0 +1,10 @@
1
+ import "moment"
2
+ import "sinon"
3
+
4
+ import "./test_helpers"
5
+ import "./format24_test"
6
+ import "./i18n_test"
7
+ import "./local_time_test"
8
+ import "./relative_date_test"
9
+ import "./strftime_test"
10
+ import "./time_ago_test"
@@ -1,3 +1,5 @@
1
+ import LocalTime from "local_time"
2
+
1
3
  {addTimeEl, assert, defer, getText, setText, test, testAsync, testGroup, triggerEvent} = LocalTime.TestHelpers
2
4
 
3
5
  testGroup "localized", ->
@@ -13,6 +15,11 @@ testGroup "localized", ->
13
15
  setText el, "2013"
14
16
  assert.equal getText(el), "2013"
15
17
 
18
+ test "processed timestamp", ->
19
+ el = addTimeEl type: "time-or-date", datetime: moment().toISOString()
20
+ assert.notOk el.getAttribute("data-processed-at")
21
+ LocalTime.run()
22
+ assert.ok el.getAttribute("data-processed-at")
16
23
 
17
24
  assertLocalized = (id, type = "time") ->
18
25
  switch type
@@ -27,7 +34,6 @@ assertLocalized = (id, type = "time") ->
27
34
 
28
35
  assert.ok datetime = el.getAttribute "datetime"
29
36
  assert.ok local = getText el
30
- assert.equal el.getAttribute("aria-label"), local
31
37
 
32
38
  datetimeParsed = moment datetime
33
39
  localParsed = moment local, momentFormat
@@ -1,3 +1,5 @@
1
+ import LocalTime from "local_time"
2
+
1
3
  {addTimeEl, assert, defer, getText, setText, test, testAsync, testGroup, triggerEvent} = LocalTime.TestHelpers
2
4
 
3
5
  testGroup "relative date", ->
@@ -82,7 +84,7 @@ testGroup "relative weekday or date", ->
82
84
  done()
83
85
 
84
86
  testAsync "before this week", (done) ->
85
- before = moment().subtract("days", 8)
87
+ before = moment("#{new Date().getFullYear()}1031", "YYYYMMDD").subtract("days", 8)
86
88
  el = addTimeEl type: "weekday-or-date", datetime: before.toISOString()
87
89
  defer ->
88
90
  assert.equal getText(el), before.format("MMM D")
@@ -1,3 +1,5 @@
1
+ import LocalTime from "local_time"
2
+
1
3
  {addTimeEl, assert, defer, getText, setText, test, testAsync, testGroup, triggerEvent} = LocalTime.TestHelpers
2
4
 
3
5
  momentMap =
@@ -26,6 +28,22 @@ momentMap =
26
28
  "%y": "YY"
27
29
  "%Y": "YYYY"
28
30
 
31
+ stubDateToLocaleString = (stubImplementation, callback) ->
32
+ original = Date.prototype.toLocaleString
33
+ Date.prototype.toLocaleString = stubImplementation
34
+ try
35
+ callback()
36
+ finally
37
+ Date.prototype.toLocaleString = original
38
+
39
+ stubDateToString = (stubImplementation, callback) ->
40
+ original = Date.prototype.toString
41
+ Date.prototype.toString = stubImplementation
42
+ try
43
+ callback()
44
+ finally
45
+ Date.prototype.toString = original
46
+
29
47
  testGroup "strftime", ->
30
48
  for day in [0..30] by 6
31
49
  do (day) ->
@@ -52,3 +70,58 @@ testGroup "strftime", ->
52
70
 
53
71
  text = getText el
54
72
  assert.ok /^(\w{3,4}|UTC[\+\-]\d+)$/.test(text), "'#{text}' doesn't look like a timezone. System date: '#{new Date}'"
73
+
74
+ testGroup "strftime time zones", ->
75
+ for timeZone in Object.keys(LocalTime.knownEdgeCaseTimeZones)
76
+ do (timeZone) ->
77
+ test "edge-case time zone #{timeZone}", ->
78
+ stub = -> "Thu Nov 30 2023 14:22:57 GMT-0000 (#{timeZone})"
79
+
80
+ stubDateToLocaleString stub, ->
81
+ el = addTimeEl format: "%Z", datetime: "2023-11-30T14:22:57Z"
82
+ LocalTime.process(el)
83
+
84
+ assert.equal getText(el), LocalTime.knownEdgeCaseTimeZones[timeZone]
85
+
86
+ test "time zones Intl can abbreviate are parsed correctly", ->
87
+ stub = (_, options) ->
88
+ if options.timeZoneName == "long"
89
+ "Thu Nov 30 2023 14:22:57 GMT-0800 (Alaska Daylight Time)" # not a known edge-case
90
+ else if options.timeZoneName == "short"
91
+ "11/30/2023, 2:22:57 PM AKDT" # possible to abbreviate
92
+
93
+ stubDateToLocaleString stub, ->
94
+ el = addTimeEl format: "%Z", datetime: "2023-11-30T14:22:57Z"
95
+ LocalTime.process(el)
96
+
97
+ assert.equal getText(el), "AKDT"
98
+
99
+ test "time zones Intl can't abbreviate are parsed by our heuristic", ->
100
+ dateToStringStub = -> "Sat Dec 02 2023 17:20:26 GMT-0600 (Central Standard Time)"
101
+ dateToLocaleStringStub = (_, options) ->
102
+ if options.timeZoneName == "long"
103
+ "Thu Nov 30 2023 14:22:57 GMT+0700 (Central Twilight Time)" # not a known edge-case
104
+ else if options.timeZoneName == "short"
105
+ "11/30/2023, 2:22:57 PM GMT+7" # not possible to abbreviate
106
+
107
+ stubDateToString dateToStringStub, ->
108
+ stubDateToLocaleString dateToLocaleStringStub, ->
109
+ el = addTimeEl format: "%Z", datetime: "2023-11-30T14:22:57Z"
110
+ LocalTime.process(el)
111
+
112
+ assert.equal getText(el), "CST"
113
+
114
+ test "time zones Intl can't abbreviate and our heuristic can't parse display GMT offset", ->
115
+ dateToStringStub = -> ""
116
+ dateToLocaleStringStub = (_, options) ->
117
+ if options.timeZoneName == "long"
118
+ "Thu Nov 30 2023 14:22:57 GMT+0700 (Central Twilight Time)" # not a known edge-case
119
+ else if options.timeZoneName == "short"
120
+ "11/30/2023, 2:22:57 PM GMT+7" # not possible to abbreviate
121
+
122
+ stubDateToString dateToStringStub, ->
123
+ stubDateToLocaleString dateToLocaleStringStub, ->
124
+ el = addTimeEl format: "%Z", datetime: "2023-11-30T14:22:57Z"
125
+ LocalTime.process(el)
126
+
127
+ assert.equal getText(el), "GMT+7"
@@ -1,8 +1,6 @@
1
- #= require moment
2
- #= require sinon-timers
1
+ import LocalTime from "local_time"
3
2
 
4
- #= require_self
5
- #= require_directory .
3
+ LocalTime.start()
6
4
 
7
5
  LocalTime.TestHelpers =
8
6
  assert: QUnit.assert
@@ -14,7 +12,7 @@ LocalTime.TestHelpers =
14
12
  done = assert.async()
15
13
  callback(done)
16
14
 
17
- addTimeEl: ({format, type, datetime} = {}) ->
15
+ addTimeEl: ({format, type, datetime, format24} = {}) ->
18
16
  format ?= "%Y"
19
17
  type ?= "time"
20
18
  datetime ?= "2013-11-12T12:13:00Z"
@@ -23,6 +21,8 @@ LocalTime.TestHelpers =
23
21
  el.setAttribute "data-local", type
24
22
  el.setAttribute "data-format", format
25
23
  el.setAttribute "datetime", datetime
24
+ if format24 then el.setAttribute "data-format24", format24
25
+
26
26
  document.body.appendChild el
27
27
  el
28
28
 
@@ -34,6 +34,9 @@ LocalTime.TestHelpers =
34
34
  # reading the text content, not a potentially arbitrary property.
35
35
  el.innerHTML
36
36
 
37
+ getTitle: (el) ->
38
+ el.getAttribute("title")
39
+
37
40
  triggerEvent: (name, el = document) ->
38
41
  event = document.createEvent "Events"
39
42
  event.initEvent name, true, true
@@ -1,3 +1,5 @@
1
+ import LocalTime from "local_time"
2
+
1
3
  {addTimeEl, assert, defer, getText, setText, test, testAsync, testGroup, triggerEvent} = LocalTime.TestHelpers
2
4
 
3
5
  testGroup "time ago", ->