Entries in mod (3)

How do I extract hours, minutes, or seconds from a time?

Short answer: Times are integers (think milliseconds).

q)(`hh`mm`ss $ .z.T), `int $ .z.T mod 1000
16 49 2 233
q)


You can extract the hours, minutes, and seconds from a time by passing `hh, `mm, and `ss, respectively, as left arguments to $ (cast):

q)now: .z.T
q)now
16:49:02.233
q)`hh $ now
16
q)`mm $ now
49
q)`ss $ now
2
q)`hh`mm`ss $ now
16 49 2
q)

Getting the milliseconds from a time is slightly less obvious. Times (type -19) are represented internally by q as 32-bit integers; typically the value counts the number of milliseconds since midnight, but it can also represent a span of time. We can cast freely back and forth between the two types and the values are preserved:

q)`time $ 0
00:00:00.000
q)`int $ 00:00:00.000
0
q)`time $ 24 * 60 * 60 * 1000
24:00:00.000
q)`int $ 24:00:00.000
86400000
q)`int $ now
60542233
q)`time $ 60542233
16:49:02.233
q)

Not only is the internal representation of time simply an integer, we can mix integers and times in integer arithmetic operations, and the result is always a time:

q)01:00:00.000 + 00:01:00.000
01:01:00.000
q)01:00:00.000 + 60000
01:01:00.000
q)01:00:00.000 * 4
04:00:00.000
q)now - 01:30:20.123
15:18:42.110
q)

By using div and mod, then, we have an alternative means to calculate the components of a time:

q)now div 3600000 // milliseconds per hour
00:00:00.016
q)now mod 1000    // just the milliseconds, please
00:00:00.233
q)

Although extracting milliseconds from a time while keeping the time type (as in the second example above) is sometimes useful, we normally want to get back these components of a time as integers, so let's cast it:

q)`int $ now mod 1000
233
q)


By the way, there is a shortcut for getting hours, minutes, and seconds from global variables that hold times: dot notation.

q)x: .z.T
q)x.hh, x.mm, x.ss
16 49 2
q)

However, we rarely use global variables to hold time values.

How do I extract the milliseconds from a time?

mod 1000:

q)now: .z.T
q)now
00:15:00.812
q)now mod 1000
00:00:00.812

If you want the milliseconds as an integer, you can simply follow the mod with a conversion to int:

q)`int$ now mod 1000
812

You don't want to pass a datetime to mod; the result you'll get is not what you had in mind. You must convert it to a time first:

q)now: .z.Z
q)now
2011.03.26T09:51:26.624
q)now mod 1000
102.4107
q)`int$ (`time$ now) mod 1000
624
q)

How do I get the day of the week?

q)`Sat`Sun`Mon`Tue`Wed`Thu`Fri .z.D mod 7
`Sat
q)\date
"Sat Mar 5 18:56:04 PST 2011"
q)

see also: -W, .z.D, mod, \