· Mar 1, 2022 5m read

How to become a time lord - The birth

Good men don’t need rules.

The Doctor.

It's not an easy task to be a master of dates and times, it is always a problem and sometimes confusing in any programming language, we are going to clarify and put a few tips to make this task as simple as possible.

Get on the TARDIS and I'm going to turn you into a Time lord


Let's start with the basics

If you usually use other languages, bear in mind that the dates in Intersystems Object Script (hereinafter IOS, not to be confused with an Apple mobile) are a bit peculiar.
When we run the command $HOROLOG in the terminal, to have the current date and time, you'll see that it is divided into two parts:


> 66149,67164

The first value is the day, to be exact the number of days since December 31st, 1840, that is, the value 1 is January 1st, 1841 and the second are the seconds since 00:00 of today.

In this example, 66149 corresponds to 09/02/2022 (Febrary 9th in european format dd/mm/yyyy) and 67164 to 18:39:24. We will call this format internal format of datet and time.

Confused? Well, we are going to start revealing the great secrets of the universe (of dates and times).


How can I convert the internal format to a clearer format?

For that, we will use the command $ZDATETIME

The basic command would be

WRITE RightNow

> 66149,67164

> 02/09/2022 18:39:24

By default, it uses the American format (mm/dd/yyyy). If you want to use the date in another format, we will use the second parameter, such as the European one (dd/mm/yyyy), in that case we will give it the value 4 (for more formats, see the documentation $ZDATETIME.dformat)

WRITE RightNow

> 66149,67164


> 09/02/2022 18:39:24

This option uses as separator and year format what we have defined in the local variables

If we also want to put another time format, for example in 12-hour format (AM/PM) instead of 24-hour format, we use the third parameter with the value 3, if we don't want to show the seconds, we will use the value 4 (see the documentation $ZDATETIME.tformat)

WRITE RightNow

> 66149,67164


> 09/02/2022 06:39:24PM


> 09/02/2022 06:39PM

Is it clearer now? So let's go deeper

ODBC Format

This format is independent of your local configuration, it will always be shown as yyyy-mm-dd, its value is 3. It's recommended to use it if we want to create data that is going to be exported in files, such as CSV, HL7 files, etc.

WRITE RightNow

> 66149,67164


> 2022-02-09 18:39:24

Day of the week, name of the day, day of the year

Value Description
10 The day of the week will be a value between 0 and 6, 0 for Sunday and 6 for Saturday.
11 The name of the abbreviated day of the week, it will return it according to the local configuration you define, the default installation of IRIS is enuw (English, United States, Unicode)
12 The name of the day of the week in long format. same as 11
14 The day of the year, so that, the number of days since January 1

If we just want to treat dates and times separately, we should use the $ZDATE and $ZTIME commands respectively. The parameters for the formats are the same as those defined in $ZDATETIME.dformat and $ZDATETIME.tformat

WRITE RightNow

> 66149,67164

WRITE $ZDATE(RightNow,10)

> 3

WRITE $ZDATE(RightNow,11)

> Wed

WRITE $ZDATE(RightNow,12)

> Wednesday

And how do I convert a date to internal format?

Well, now we're going to see the opposite step, that is, have a text with a date and convert it into IOS format. For this thask, we'll use the command $ZDATETIMEH

This time, we have to indicate what format the date and time are in (if we are using $ZDATETIMEH) or the date ($ZDATEH) or the time ($ZTIMEH) separately.

The formats are the same, that is, if we have a string with the date in ODBC format (yyyy-mm-dd), then we'll use the value 3

SET MyDatetime = "2022-02-09 18:39:24"
SET Interna1 = $ZDATETIMEH(MyDatetime, 3, 1) // ODBC Format

SET MyDatetime = "09/02/2022 18:39:24"
SET Interna2 = $ZDATETIMEH(MyDatetime, 4, 1) // European format

SET MyDatetime = "02/09/2022 06:39:24PM"
SET Interna3 = $ZDATETIMEH(MyDatetime, 1, 3) // American format with time in 12h AM/PM
WRITE Interna1,!,Interna2,!,Interna3

> 66149,67164

Logically, if we say that the string is using a especific format and we give it the wrong parameter, anything can happen, like instead of February 9th it understands as September 2nd.

Do not mix formats, that later come the problems.

SET MyDatetime = "09/02/2022"

/// American format
SET InternalDate = $ZDATEH(MyDatetime, 1) 

/// European format
SET OtherDate = $ZDATETIME(InternalDate, 4)
WRITE InternalDate,!,OtherDate

> 66354

Needless to say, if we try to set a European date and try to transform it into an American one... What would happen on Valentine's Day?

SET MyDatetime = "14/02/2022"
SET InternalDate = $ZDATEH(MyDatetime, 1) // American format. month 14 doesn't exists!!!

Well, like all Valentine's day... broken hearts, well... in this case, broken code.

Well, let's do something with what you've already learned.

READ !,"Please indicate your date of birth (dd/mm/yyyy): ",dateOfBirth
SET internalFormat = $ZDATEH(dateOfBirth, 4)
SET dayOfWeek= $ZDATE(internalFormat, 10)
SET nameOfDay = $ZDATE(internalFormat, 12)
WRITE !,"The day of the week of your birth is: ",nameOfDay
IF dayOfWeek = 5 WRITE "you always liked to party!!!" // was born on friday

Later we will see other ways of doing things, and how to handle errors.


Next chapter: How to travel in time



If you want to know why the value of 01/01/1841 is taken as the value 1, it comes because this date was chosen because it was the non-leap year before the birth of the oldest living US citizen, who was a civil war veteran 121 years old when the MUMPS programming language was designed, from which it extends Object Script

Discussion (3)3
Log in or sign up to continue

gracias for such a detailed and emotional story about the type of date/time - it caught on :)

I was catching this topic a bit in my article about physical units in programming languages: DataOps: Let's learn how to work with physical objects in IRIS

On such " fuzzy " objects as date/time, you want to get a universal method of use with minimization of errors. 
It seems to me that maximum use of built-in IRIS type can help here. And do the conversion on the edges of interaction - only in the interface modules.

What do you think?