Slide 1

Slide 1 text

Which Time Is It?

Slide 2

Slide 2 text

"Time" has many meanings in English

Slide 3

Slide 3 text

Choosing the right time: Better design and avoids bugs

Slide 4

Slide 4 text

What is the difference between 1.day and 1.day.ago?

Slide 5

Slide 5 text

Two Kinds of Time Moment November 14th, 2023 at 10:30AM PST Duration 45 minutes

Slide 6

Slide 6 text

Visualizing the difference

Slide 7

Slide 7 text

Timeline

Slide 8

Slide 8 text

Moment Points on the timeline

Slide 9

Slide 9 text

Duration Distance on the timeline

Slide 10

Slide 10 text

Not 1d vectors!

Slide 11

Slide 11 text

CLASSES PROVIDED BY Ruby

Slide 12

Slide 12 text

MOMENT DateTime

Slide 13

Slide 13 text

MOMENT DateTime Deprecated

Slide 14

Slide 14 text

MOMENT (NANOSECOND RESOLUTION) Time Nov 14, 2023 10:30:05.123456789 AM PST

Slide 15

Slide 15 text

Time Nanoseconds apart

Slide 16

Slide 16 text

MOMENT (DAY RESOLUTION) Date Nov 14, 2023

Slide 17

Slide 17 text

Date Days apart

Slide 18

Slide 18 text

Resolution impacts enumeration start = Date.new(2023, 11, 12) finish = Date.new(2023, 11, 15) (start..finish).map(&:to_s) # 2023-11-12 # 2023-11-13 # 2023-11-14 # 2023-11015

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Notice: It's all the same kind of time!

Slide 21

Slide 21 text

Date/Time for moments and numerics for durations Core Ruby represents time with

Slide 22

Slide 22 text

Math! Not all operations make sense

Slide 23

Slide 23 text

Time docs Interesting method signatures

Slide 24

Slide 24 text

Time#+ time + numeric -> time

Slide 25

Slide 25 text

time + numeric -> time Notice: We can't add two time instances!

Slide 26

Slide 26 text

What question is this asking?

Slide 27

Slide 27 text

What point is 45 mins after point A? ADDITION IS ASKING:

Slide 28

Slide 28 text

Time#+ What point is 45 mins after point A?

Slide 29

Slide 29 text

Time#- time - numeric -> time time - other_time -> float

Slide 30

Slide 30 text

Notice: there are 2 signatures!

Slide 31

Slide 31 text

What questions is this asking?

Slide 32

Slide 32 text

What point is 45 mins before point A? SUBTRACTION IS ASKING:

Slide 33

Slide 33 text

time - numeric -> time What point is 45 mins before point A?

Slide 34

Slide 34 text

time - time -> float Notice: we can subtract two points!

Slide 35

Slide 35 text

What questions is this asking?

Slide 36

Slide 36 text

How big is the duration between points A and B? SUBTRACTION IS ASKING:

Slide 37

Slide 37 text

time - time -> float What is the distance between points A and B?

Slide 38

Slide 38 text

3 questions we can answer about the same data

Slide 39

Slide 39 text

Same equation, rearanged point1 + duration = point2 (Time#+) point2 - duration = point1 (Time#- v1) point2 - point1 = duration (Time#- v2)

Slide 40

Slide 40 text

What it you need a time without an associated day?

Slide 41

Slide 41 text

Other Kinds of Time Moment November 14th, 2023 at 11:30AM PST Duration 45 minutes Time of Day 5:30 PM

Slide 42

Slide 42 text

Time of Day Points on a circular timeline

Slide 43

Slide 43 text

How does ToD interact with other types?

Slide 44

Slide 44 text

Time of Day Our 3 questions still work!

Slide 45

Slide 45 text

Extract from a Time

Slide 46

Slide 46 text

Combine ToD with Date to get a Time

Slide 47

Slide 47 text

Third Party Solutions GEMS!

Slide 48

Slide 48 text

DURATION ActiveSupport third party gems

Slide 49

Slide 49 text

DURATION 1.day

Slide 50

Slide 50 text

POINT IN TIME 1.day.ago

Slide 51

Slide 51 text

Sugar Time.now - (1 * SECONDS_PER_DAY)

Slide 52

Slide 52 text

TIME OF DAY jackc/tod third party gems

Slide 53

Slide 53 text

How to Implement Time?

Slide 54

Slide 54 text

Warning

Slide 55

Slide 55 text

Avoid human-readable integers like 1030

Slide 56

Slide 56 text

Invalid times like 3176

Slide 57

Slide 57 text

Breaks Math (1025 - 0925 = 100)

Slide 58

Slide 58 text

Avoid multi-part values like {hour: 10, minute: 30}

Slide 59

Slide 59 text

Epoch + Counter

Slide 60

Slide 60 text

Epoch: when is 0?

Slide 61

Slide 61 text

Counter: how many since 0?

Slide 62

Slide 62 text

Common Implementations UNIX Time milliseconds since Jan 1, 1970 Postgres Time of Day microseconds since midnight Ruby Date days since Jan 1, 4713 BCE

Slide 63

Slide 63 text

Just a big counter class TimeOfDay def initialize(microseconds_since_midnight) @counter = (microseconconds_since_midnight % MS_PER_DAY) end end

Slide 64

Slide 64 text

Custom constructor class TimeOfDay def self.from_parts(hours:, minutes:, seconds:) total = (hours * MICROSECONDS_PER_HOUR) + (minutes * MICROSECONDS_PER_MINUTE) + (seconds * MICROSECONDS_PER_SECOND) new(total) end end

Slide 65

Slide 65 text

Operators class TimeOfDay def +(duration_microseconds) self.class.new(@counter + duration_microseconds) end end

Slide 66

Slide 66 text

Case Study

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

When working with time Think About What kind of time you need moment, duration, tod, etc What operations make sense (and which ones don't!) both within and across types What resolution you need e.g. Time vs Date class

Slide 69

Slide 69 text

Joël Quenneville Joël Quenneville Principal Developer thoughtbot @joelquen bikeshed.fm co-host