doc • date

Date & time management

There is a lot of confusion among all users, not only newbies, about how to use the Date datatype correctly in Gambas. This page will try to clear it up.

Dates are not strings

The confusion mainly comes from the fact that you are thinking about dates by using its locale string representation, i.e. as if the Date datatype would represent a locale date. Big mistake!

Internally, Gambas stores a Date value in Universal Time (a.k.a. "UTC"), using two 32 bits integer:

  • The first integer is a number of days since a specific epoch, which is January 1st, 4801 BC. It's the date part.

  • The second integer is a number of milliseconds since midnight. It's the time part.

In other words, a Gambas date/time value is an absolute timestamp.

That notion of absolute time is a practical computing choice. It is an an approximation of what time actually is in physical sciences.

But there is no way in Gambas to directly write a Date constant. You always has to use either the Date function that builds a date or convert a string representation of the date by using CStr, CDate, Str$ or Val.

Consequently, each time you manipulate a date representation, Gambas has to decide if your date representation is in U.T.C. or in local time. In other words, the timezone associated with a date representation is implicit.

It's a bit like the problem of string charsets: the charset of a string is implicit. It is not stored with the string.

Gambas functions either assume that a date representation is:

  • In U.T.C., using an American date format

  • In local time, i.e. in the timezone specified by the System.TimeZone property, which comes directly from the current system configuration. The date format is the local date format.

The timezone depends on what is configured in your system, and when you convert the date into a string (timezone can change during the year, or because of sudden political decisions). The date format depends on the current language specified by the System.Language property.

Here is the list of date-related functions, and if they deal with U.T.C. or local time.

Functions that deal with U.T.C. and American date format

CDate Converts an expression into a date & time value.
CStr Converts a date & time value into a string.

These functions are used by the interpreter when doing implicit datatype conversion.

Functions that deal with local time

Date Returns a date without its time component, or create a date & time value from its components in local time.
DateAdd Adds a period to a given date.
DateDiff Returns the period between two dates.
Day Returns the day of a Date value
Hour Returns the hours of a Date value.
Minute Returns the minutes of a Date value.
Month Returns the month of a Date value.
Second Returns the seconds of a Date value.
Str$ Converts a date & time value into a string.
Time Returns the time part of a Date value, or create a time value from its components.
Val Converts a string into a date & time value, provided that the string represents a date in local date & time format.
Week Returns the week number of a Date value.
WeekDay Returns the week day of a Date value.
Year Returns the year of a Date value.

Implicit conversion

Beware with implicit conversion between dates and strings!

  • PRINT prints a date by using the Str$ method. So the date is printed in local time.

  • All other implicit conversions use the CStr and CDate functions, assuming U.T.C. time.

CStr and CDate intend to be reciprocal. It means that

CStr(CDate(SomeString)) = SomeString

and

CDate(CStr(SomeDate)) = SomeDate

should always be true.

Dates are numbers

A date & time value is implicitly converted to a floating point number whose integer part is the internal date part (the number of days since January 1st, 4801 BC), and fractional part is the internal time part.

Consequently, you can easily do day arithmetic between dates using the standard + and - operators.

As for the fractional part, you must be careful that you are in U.T.C. time, and that a zero fractional part means midnight in U.T.C. time.

Consequently, if your timezone is not null, CFloat(Date(Now)) will not return an integer!

Null dates and time-only dates

Time-only dates are date & time value where only the date part is zero. In that special case, the timezone is not taken into account. This is useful when you want to do arithmetic with times.

Null dates are date & time values where both date and time parts equal zero. They are equivalent to the NULL constant. Doing arithmetic with null dates raises an error.

Storing dates

The only way of storing dates in a reliable way is using the UTC representation. Never store a date in local representation!

Storing dates inside a binary file

You have to use the WRITE and READ instructions with the As Date syntax.

That way you will write the UTC internal representation of the date value directly in the file.

Storing dates inside a text file

You must write and read the UTC string representation of the date value, by using the CStr and CDate functions.

You can use CFloat on the date value too, to store the internal date timestamp as a floating point value. It works as well, but is less readable.

Otherwise, you can use any custom representation (Unix timestamp for example), provided that it is a constant shift from the absolute UTC time.

Dates and calendars

For the specific problem of date-only representation, see Dates and calendars.