Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

@mybluewristband Jennifer Wong Mode analytics Mozilla tech speaker whovian

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

@mybluewristband @mybluewristband

Slide 6

Slide 6 text

@mybluewristband QUE PASÓ? What happened? ?

Slide 7

Slide 7 text

@mybluewristband RECURRING INVITES A past project @mybluewristband

Slide 8

Slide 8 text

@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

Slide 9

Slide 9 text

@mybluewristband @mybluewristband

Slide 10

Slide 10 text

@mybluewristband @mybluewristband

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

@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

Slide 13

Slide 13 text

@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

Slide 14

Slide 14 text

@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)

Slide 15

Slide 15 text

“ @mybluewristband Don't write your own recurrence rule library. Doubly so for JavaScript. Jennifer Wong

Slide 16

Slide 16 text

“ @mybluewristband Check the timezone of your CI server. Doubly so if it's running JavaScript tests. Jennifer Wong

Slide 17

Slide 17 text

@mybluewristband EL TIEMPO ES RARO Time is weird. @mybluewristband

Slide 18

Slide 18 text

@mybluewristband @mybluewristband

Slide 19

Slide 19 text

@mybluewristband EL TIEMPO Tale as old as time @mybluewristband

Slide 20

Slide 20 text

@mybluewristband

Slide 21

Slide 21 text

@mybluewristband

Slide 22

Slide 22 text

@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

Slide 23

Slide 23 text

@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)

Slide 24

Slide 24 text

@mybluewristband G M T !!! @mybluewristband

Slide 25

Slide 25 text

@mybluewristband JAVASCRIPT DATE OBJECT It's old

Slide 26

Slide 26 text

@mybluewristband @mybluewristband

Slide 27

Slide 27 text

@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()

Slide 28

Slide 28 text

@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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

@mybluewristband @mybluewristband

Slide 33

Slide 33 text

@mybluewristband TYPE COERCION One can coerce a date to a number of milliseconds from the Unix Epoch simply by using: +new Date() @mybluewristband

Slide 34

Slide 34 text

@mybluewristband JAVASCRIPT VERSUS MOMENT.JS FIGHT! @mybluewristband

Slide 35

Slide 35 text

@mybluewristband GETTERS Go get 'em

Slide 36

Slide 36 text

// 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

Slide 37

Slide 37 text

// 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

Slide 38

Slide 38 text

@mybluewristband SETTERS Get, set, match (?) @mybluewristband

Slide 39

Slide 39 text

// 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

Slide 40

Slide 40 text

// 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

Slide 41

Slide 41 text

@mybluewristband OTHER METHODS I've got gadgets and gizmos a-plenty @mybluewristband

Slide 42

Slide 42 text

@mybluewristband

Slide 43

Slide 43 text

// 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

Slide 44

Slide 44 text

// 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

Slide 45

Slide 45 text

@mybluewristband LOCALE STRINGS Whoa @mybluewristband

Slide 46

Slide 46 text

@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()

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

@mybluewristband

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

@mybluewristband

Slide 52

Slide 52 text

@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()

Slide 53

Slide 53 text

@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()

Slide 54

Slide 54 text

@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()

Slide 55

Slide 55 text

@mybluewristband MOMENT.JS A library! @mybluewristband

Slide 56

Slide 56 text

@mybluewristband ENTONCES, POR QUE MOMENT? ?

Slide 57

Slide 57 text

@mybluewristband

Slide 58

Slide 58 text

@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

Slide 59

Slide 59 text

@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

Slide 60

Slide 60 text

@mybluewristband OMG TIMEZONES ⚠ ⚠ ⚠ ⚠ ⚠ $ vs & @mybluewristband

Slide 61

Slide 61 text

@mybluewristband

Slide 62

Slide 62 text

@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 }

Slide 63

Slide 63 text

@mybluewristband ENTONCES ... ¿QUAL DEBEMOS USAR? Oh no se...

Slide 64

Slide 64 text

@mybluewristband

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

@mybluewristband You’ll

Slide 67

Slide 67 text

@mybluewristband BUT DON’T TAKE MY ADVICE Do what's best for your team and your need to scale @mybluewristband

Slide 68

Slide 68 text

@mybluewristband

Slide 69

Slide 69 text

@mybluewristband TEMPORAL A tc39 proposal

Slide 70

Slide 70 text

@mybluewristband

Slide 71

Slide 71 text

@mybluewristband

Slide 72

Slide 72 text

@mybluewristband ❤❤❤❤❤

Slide 73

Slide 73 text

@mybluewristband MAS COSAS

Slide 74

Slide 74 text

@mybluewristband Zell Liew for CSS Tricks!

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

@mybluewristband

Slide 77

Slide 77 text

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