$30 off During Our Annual Pro Sale. View Details »

Time is but an Illusion.. in JavaScript! (JSConf CO)

October 18, 2019

Time is but an Illusion.. in JavaScript! (JSConf CO)

With so much to worry about timing wise: formatting, time zones, internationalization, recurrence rules, leap years, daylight savings time, and more, everyone needs HELP!

Let’s turn time into money by taking a look at the most popular time libraries and how we use them to solve JavaScript’s time problems. We’ll look at how JavaScript’s Date object started and what its prototype allows. We’ll wind our way through dates, times, and standards to find solutions to the weirdness.

Let’s kill time together talking about JavaScript time! Because we know, time heals all.


October 18, 2019

More Decks by Jenn

Other Decks in Technology


  1. @mybluewristband TIME.. IS BUT AN ILLUSION IN JAVASCRIPT! @mybluewristband

  2. @mybluewristband QUIEN ERES TU? Who are you? ? @mybluewristband @mybluewristband

  3. @mybluewristband Jennifer Wong Mode analytics Mozilla tech speaker whovian

  4. @mybluewristband DOCTOR WHO Time Lord Sonic Screwdriver T.A.R.D.I.S Daleks @mybluewristband

  5. @mybluewristband @mybluewristband

  6. @mybluewristband QUE PASÓ? What happened? ?

  7. @mybluewristband RECURRING INVITES A past project @mybluewristband

  8. @mybluewristband RECURRING INVITES Generate an recurrence rule (rrule) on the

    frontend (???) in iCal format All existing rrule libraries were 1.5+ years out of date But now there is an updated one: https://github.com/jakubroztocil/rrule So I wrote my own rrule library… Ensure timezone attached to rrule Timezone of office location, not employee Employees are based all over the world May create invites for people in other offices
  9. @mybluewristband @mybluewristband

  10. @mybluewristband @mybluewristband

  11. @mybluewristband FREQ=WEEKLY; BYDAY=FR; UNTIL=20190629T120000Z;

  12. @mybluewristband RECURRING INVITES - A PROBLEM We were in PST

    or GMT-7/GMT-8 (daylight savings) All tests would pass locally At 4pm/5pm PST/PDT, all frontend CI tests would fail for a few hours
  13. @mybluewristband RECURRING INVITES - A PROBLEM Some tests written with

    assuming a specific time zone (PST/PDT) But the CI server was in a different timezone Tests didn’t expect that times minutes or hours apart might be in different days
  14. @mybluewristband RECURRING INVITES - A SOLUTION KINDA Local testing vs

    CI testing issues Resolution: set a particular time/time zone in a test But this only reliably tests that specific time/time zone Also, undo any time mocking or the next test(s) will use the same time/time zone (and probably fail)
  15. “ @mybluewristband Don't write your own recurrence rule library. Doubly

    so for JavaScript. Jennifer Wong
  16. “ @mybluewristband Check the timezone of your CI server. Doubly

    so if it's running JavaScript tests. Jennifer Wong
  17. @mybluewristband EL TIEMPO ES RARO Time is weird. @mybluewristband

  18. @mybluewristband @mybluewristband

  19. @mybluewristband EL TIEMPO Tale as old as time @mybluewristband

  20. @mybluewristband

  21. @mybluewristband

  22. @mybluewristband HISTORY OF TIME https://en.wikipedia.org/wiki/Time Artifacts from the Paleolithic suggest

    the moon was used to reckon time Lunar calendars first appeared Years of either 12 or 13 lunar months (354 or 384 days) The earliest lunar calendar was discovered in 8000 BC. Egyptians created the first of several time measurement devices T-square Sundial Water clock
  23. @mybluewristband TYPES OF TIME ZONES OR STANDARDS Greenwich Mean Time

    (GMT) Created in 1847 at the Royal Observatory in Greenwich Universal Coordinated Time (UTC) International Meridian Conference (of 26 nations) $ Colombia was there! & The United States was there! Unix Time Number of seconds that have passed since the Unix Epoch 00:00:00 UTC Thursday, 1 January 1970 International Standards Organization (ISO)
  24. @mybluewristband G M T !!! @mybluewristband

  25. @mybluewristband JAVASCRIPT DATE OBJECT It's old

  26. @mybluewristband @mybluewristband

  27. @mybluewristband ECMA-262 JavaScript! Version 1 - 1997 Only six new

    Date object methods have been added since then Date.prototype.toDateString() Date.prototype.toISOString() Date.prototype.toJSON() Date.prototype.toLocaleDateString() Date.prototype.toLocaleTimeString() Date.prototype.toTimeString()
  28. @mybluewristband WHY THE 0 INDEX JavaScript’s Date object has a

    zero indexed month java.util.Date had 0-indexed month java.time package was released in 2014 with a 1-indexed month Moment.js uses a zero indexed month
  29. @mybluewristband https://stackoverflow.com/questions/2552483/why-does-the-month-argument-range-from-0-to-11-in- javascripts-date-constructor/41992352#41992352

  30. @mybluewristband https://stackoverflow.com/questions/2552483/why-does-the-month-argument-range-from-0-to-11-in- javascripts-date-constructor/41992352#41992352

  31. “ @mybluewristband Because Java. Brendan Eich (creator of JavaScript)

  32. @mybluewristband @mybluewristband

  33. @mybluewristband TYPE COERCION One can coerce a date to a

    number of milliseconds from the Unix Epoch simply by using: +new Date() @mybluewristband
  34. @mybluewristband JAVASCRIPT VERSUS MOMENT.JS FIGHT! @mybluewristband

  35. @mybluewristband GETTERS Go get 'em

  36. // Date Object Date.prototype.constructor Date.prototype.getDate() Date.prototype.getDay() Date.prototype.getFullYear() Date.prototype.getHours() Date.prototype.getMilliseconds() Date.prototype.getMinutes()

    Date.prototype.getMonth() Date.prototype.getSeconds() Date.prototype.getTime() Date.prototype.getTimezoneOffset() // Moment.js moment() moment().date() moment().day() moment().year() moment().hour() moment().millesecond() moment().minute() moment().month() moment().second() moment().get() moment().zone() // deprecated @mybluewristband
  37. // Date Object Date.prototype.getUTCDate() Date.prototype.getUTCDay() Date.prototype.getUTCFullYear() Date.prototype.getUTCHours() Date.prototype.getUTCMilliseconds() Date.prototype.getUTCMinutes() Date.prototype.getUTCMonth()

    Date.prototype.getUTCSeconds() // Moment.js moment().utc().date() moment().utc().day() moment().utc().year() moment().utc().hour() moment().utc().milleseconds() moment().utc().minutes() moment().utc().month() moment().utc().seconds() @mybluewristband
  38. @mybluewristband SETTERS Get, set, match (?) @mybluewristband

  39. // Date Object Date.prototype.setDate() Date.prototype.setFullYear() Date.prototype.setHours() Date.prototype.setMilliseconds() Date.prototype.setMinutes() Date.prototype.setMonth() Date.prototype.setSeconds()

    Date.prototype.setTime() Date.prototype.setYear() // deprecated // Moment.js moment().date() moment().year() moment().hour() moment().millesecond() moment().minute() moment().month() moment().second() moment().set() moment().year() @mybluewristband
  40. // Date Object Date.prototype.setUTCDate() Date.prototype.setUTCFullYear() Date.prototype.setUTCHours() Date.prototype.setUTCMilliseconds() Date.prototype.setUTCMinutes() Date.prototype.setUTCMonth() Date.prototype.setUTCSeconds()

    // Moment.js moment().utc().date() moment().utc().year() moment().utc().hour() moment().utc().milleseconds() moment().utc().minutes() moment().utc().month() moment().utc().seconds() @mybluewristband
  41. @mybluewristband OTHER METHODS I've got gadgets and gizmos a-plenty @mybluewristband

  42. @mybluewristband

  43. // Date Object Date.prototype.toDateString() Date.prototype.toISOString() Date.prototype.toJSON() Date.prototype.valueOf() // Returns milliseconds

    since // the Unix epoch which is // 1 January 1970 00:00:00 UTC // Moment.js moment().format('ddd MMM DD YYYY’) moment().utc().format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z' moment().utc().format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z' parseInt( moment().format('x'), 10 ) // Returns the string version of milliseconds since // Unix epoch then parses into an integer @mybluewristband
  44. // Date Object Date.prototype.toString() // e.g. Thu Oct 10 2019

    22:46:02 // GMT-0700 (Pacific Daylight Time) Date.prototype.toTimeString() // e.g. 22:46:02 GMT-0700 // (Pacific Daylight Time) Date.prototype.toUTCString() // e.g. Fri, 11 Oct 2019 // 05:46:02 GMT // Moment.js moment().toDate().toString() // Translate into a Date object // then run .toString() on it moment().toDate().toTimeString() // Translate into a Date object // then run .toString() on it moment().utc().format( 'ddd, DD MMM YYYY HH:mm:ss' ) + ' GMT' @mybluewristband
  45. @mybluewristband LOCALE STRINGS Whoa @mybluewristband

  46. @mybluewristband LOCALE STRINGS Super cool! // Date Object Date.prototype.toLocaleDateString() Date.prototype.toLocaleString()

    Date.prototype.toLocaleTimeString() // Moment.js moment().format('L') moment().format('L, LTS') moment().format(‘LTS') moment().locale()
  47. var event = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

    var options = { weekday: ‘long', year: ‘numeric', month: ‘long', day: ‘numeric’ }; console.log(event.toLocaleDateString('de-DE', options)); // expected output: Donnerstag, 20. Dezember 2012 console.log(event.toLocaleDateString('ar-EG', options)); // expected output: ٢٠١٢ ،ﺮﺒﻤﺴﯾد ٢٠ ،ﺲﯿﻤﺨﻟا console.log(event.toLocaleDateString('ko-KR', options)); // expected output: 2012֙ 12ਘ 20ੌ ݾਃੌ @mybluewristband
  48. @mybluewristband

  49. None
  50. None
  51. @mybluewristband

  52. @mybluewristband DEPRECATED Returned a two digit OR four digit year

    People didn’t think we’d live beyond the Mayan calendar https://developer.mozilla.org/en-US/ docs/Web/JavaScript/Reference/ Global_Objects/Date/getYear Date.prototype.getYear() Date.prototype.setYear()
  53. @mybluewristband DEPRECATED Converts a date to a string, using Internet

    Greenwich Mean Time (GMT) conventions Exact format of the return value varies according to the platform and browser… https://developer.mozilla.org/en-US/ docs/Web/JavaScript/Reference/ Global_Objects/Date/toGMTString Date.prototype.toGMTString()
  54. @mybluewristband NON STANDARD Converts a date to a string using

    the specified formatting Does not use Intl.DateTimeFormat Intl.DateTimeFormat formats dates in a standards-compliant way Deprecated as of Firefox 58+ Date.prototype.toLocaleFormat()
  55. @mybluewristband MOMENT.JS A library! @mybluewristband

  56. @mybluewristband ENTONCES, POR QUE MOMENT? ?

  57. @mybluewristband

  58. @mybluewristband MORE GETTERS MOMENT.JS OFFERS moment().quarter() // Returns the year’s

    quarter moment().weekday() // Returns locale aware day of week moment().week() // Returns the week of the year moment().dayOfYear() // Returns the number day of the year from 1-366 moment().weeksInYear() // Returns the number of weeks in a specific year moment().unix() // Unix time in seconds
  59. @mybluewristband DATE TIME MATH IS EASY 1-2-3 moment().add() // Add

    to any part(s) of a date moment().subtract() // Subtract from any part(s) of a date moment().startOf() // Sets any part of a date to the beginning moment().endOf() // Sets any part of a date to the end moment().local() // Set time to the local time zone moment().utc() // Set time to the equivalent UTC time zone moment().utcOffset() // Returns the UTC offset in minutes
  60. @mybluewristband OMG TIMEZONES ⚠ ⚠ ⚠ ⚠ ⚠ $ vs

    & @mybluewristband
  61. @mybluewristband

  62. @mybluewristband Docs: https://momentjs.com/timezone/ Create moments with timezones Easily edit those

    timezones MOMENT TIMEZONE moment.tz() // Create a moment with a time zone or edit the timezone. moment.tz.Zone { name : 'America/Los_Angeles', // the unique identifier abbrs : ['PDT', 'PST'], // the abbreviations untils : [1414918800000, 1425808800000], // the timestamps in milliseconds offsets : [420, 480] // the offsets in minutes }
  63. @mybluewristband ENTONCES ... ¿QUAL DEBEMOS USAR? Oh no se...

  64. @mybluewristband

  65. “ @mybluewristband Just use JavaScript until you can't anymore! Jennifer

  66. @mybluewristband You’ll

  67. @mybluewristband BUT DON’T TAKE MY ADVICE Do what's best for

    your team and your need to scale @mybluewristband
  68. @mybluewristband

  69. @mybluewristband TEMPORAL A tc39 proposal

  70. @mybluewristband

  71. @mybluewristband

  72. @mybluewristband ❤❤❤❤❤

  73. @mybluewristband MAS COSAS

  74. @mybluewristband Zell Liew for CSS Tricks!

  75. None
  76. @mybluewristband

  77. @mybluewristband ¡MUCHAS GRACIAS! ¿Preguntas? Jennifer Wong @mybluewristband https://github.com/jennz0r