Gambas Documentation
Application Repository
Code Snippets
Compilation & Installation
Components
Controls pictures
Deprecated components
Developer Documentation
Development Environment Documentation
Documents
About The Best Formula In The World
Architecture details
Benchmarks
Books
By Reference Argument Passing
Compatibility between versions
Creating And Using Libraries
Database Datatype Mapping
Database Request Quoting
Date & time management
Dates and calendars
DBus and Gambas
Differences Between Shell And Exec
Differences From Visual Basic
Distributions & Operating Systems
Drag & Drop
DrawingArea Internal Behaviour
External functions datatype mapping
Frequently Asked Questions
Gambas Farm Server Protocol
Gambas Mailing List Netiquette
Gambas Markdown Syntax
Gambas Naming Conventions
Gambas Object Model
Gambas Scripting
Gambas Server Pages
Gambas Unit Testing
Gambas Wiki Markup Syntax
Getting Started With Gambas
Hall Of Fame
Image Management In Gambas
Including Help Comments in Source Code
Interpreter limits
Introduction
Just In Time Compiler
Just In Time Compiler (old version)
License
Localisation and Internationalization
Mailing Lists & Forums
Naming Conventions
Network Programming
ODBC Component Documentation
PCRE Pattern Syntax
Porting from Gambas 2 to Gambas 3
Previous News
Project Directory Structure
Release Notes
Reporting a problem, a bug or a crash
Rich Text Syntax
Screenshots
Text highlighting definition file syntax
The Program has stopped unexpectedly by raising signal #11
Variable Naming Convention
WebPage Syntax
Web site home page
What Is Gambas?
Window & Form Management
Window Activation & Deactivation
Window Life Cycle
XML APIs
Error Messages
Gambas Playground
How To's
Language Index
Language Overviews
Last Changes
Lexicon
README
Search the wiki
To Do
Topics
Tutorials
Wiki License
Wiki Manual

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!

Internal representation

Internally, Gambas stores a Date value using two 32 bits integer:
  • The first integer is a number of days since the origin, a specific instant in the past. It's the date part. Each day is supposed to be exactly 86,400 seconds, which is an approximation.

  • The second integer is a number of milliseconds added to that number of days. 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's not important how Gambas internally stores its Date datatype.

The important thing you must clearly put in your mind: Gambas Dates are not dates in the usual meaning, but instants, i.e. points in time.

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.

Since 3.18

Since Gambas 3.18, the timezone can be explicitly specified in a date string representation.

The syntax is:

<Old date string representation> <space> [ UTC | GMT ] [ + | - ] HH [ :MM ]

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 the origin), and fractional part is the internal time part.

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

At the moment, the origin instant is at midnight in UTC 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! Or at least always use the same timezone.

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.

Beware that the internal representation may change, so you should normally not assume that the binary value will have the same meaning in the future.

But if that internal representation changes, READ and WRITE will be modified to be backward-compatible, so you finally can assume that the binary value emitted by READ will stay the same.

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.