• Solutions
    • FERC XBRL Reporting
    • FDTA Financial Reporting
    • SEC Compliance
    • Windows Clipboard Management
    • Legato Scripting
  • Products
    • GoFiler Suite
    • XBRLworks
    • SEC Exhibit Explorer
    • SEC Extractor
    • Clipboard Scout
    • Legato
  • Education
    • Training
    • SEC and EDGAR Compliance
    • Legato Developers
  • Blog
  • Support
  • Skip to blog entries
  • Skip to archive page
  • Skip to right sidebar

Friday, January 06. 2017

Legato Developers Corner #16: What Time Is It? Date and Time Functions

Legato has several functions to help manage displaying and tracking time. It might be very useful to know, for example, how long has it been since the last action was performed. Say you want to run a task every five minutes. Well, you need some way to check to see if five minutes has elapsed or not. Additionally, if you want to display time to a user, you need to make sure that the time is displayed in an intelligible format, not just a number of milliseconds seconds since 1970 or something equally useless to anyone except a machine. This article will discuss a few of the functions that simplify this.



Example script of functions discussed in this post: 


#define			FIVE_DAYS		4320000000000

string			datestring;
qword			filetime;
qword			futuretime;
int			unixtime;

// We can get the current filetime and print it out
filetime = GetLocalTime();
AddMessage("Filetime: %d",filetime);

// We can convert it to UNIX time and print it out
unixtime = DateToUnix(filetime);
AddMessage("Unix Time: %d",unixtime);

// We can convert the filetime to a formatted string, and print 
// out a few examples of different formats
datestring = FormatDate(filetime);
AddMessage("Default String Format: %s",datestring);

datestring = FormatDate(filetime,"l, F dS, Y");
AddMessage("Using a Custom Defined Format: %s",datestring);

datestring = FormatDate(filetime, DS_DATE_AT_TIME);
AddMessage("Using a Legato Defined Format: %s",datestring);


// We can use simple math to get five days from now, and print it
// out in a nice date format
futuretime = filetime + FIVE_DAYS;
datestring = FormatDate(futuretime,"l, F dS, Y");
AddMessage("Five Days From Now: %s",datestring);

// StringToDate can try to handle a poorly formatted date and make it
// a normalized format in Windows filetime
datestring = "2-20/17";
filetime = StringToDate(datestring, SD_AMERICAN);
datestring = FormatDate(filetime,"l, F dS, Y");
AddMessage("Reformatted Time: %s",datestring);

// When using StringToDate, you may want to test if it was understood or
// not. If the GetLastError function is ERROR_SYNTAX, it means the date 
// was not understood.
datestring = "2-20, Two Thousand Seventeen";
filetime = StringToDate(datestring, SD_AMERICAN);
if(GetLastError()==ERROR_SYNTAX){
    AddMessage("Cannot convert date %s, unknown format",datestring);
    }
    
// Converting from well-formed MySQL date times is also possible with
// StringToDate.
datestring = "2017-01-05 12:00:00";
filetime = StringToDate(datestring, SD_AMERICAN);
if(GetLastError()==ERROR_SYNTAX){
    AddMessage("Cannot convert date, unknown format");
    }
else{
    AddMessage("Converted MySQL Date is: %d",filetime);
    datestring = FormatDate(filetime,"1, F dS, Y");
    AddMessage("Reformatted MySQL Date is: %s", datestring);
    }

For comparing dates or doing any sort of math with dates, you need to use date-time values. These are stored in Legato as 64-bit qwords, based on the Filetime format described in the Windows SDK. They represent the number of 100 nanosecond intervals since January 1, 1601. With this number, you can store dates as numbers and easily compare them against each other. Legato provides a script function to get this value, called the GetLocalTime function. Once you have this number, you can add a number of 100 nanosecond intervals to it in order to get the time of a future event or subtract time from it. So if you want to get five days from now, it would be the result from the GetLocalTime SDK function plus 4320000000000 100-nanosecond intervals. As we did above, you can store values like that number of intervals using the define statement in your script to make the code more readable.

 

Comparing dates is easy with this as well. Use normal “less than” (<) and “greater than: (>) operators. Testing for equivalence is a bit trickier because with such a high resolution of the date-time value, you might need to write a function to see if they are equal enough to your particular purpose. If two dates happened within 1 second of each other, for example, is that enough to consider them equal? You could get the difference and compare it against a number of 100-nanosecond intervals, and if the difference is less than that, your function could return true for equivalence.


Another common type of date-time value that you may encounter is POSIX time, also known as Unix time, or Epoch time. This is the number of seconds since January 1, 1970. It is commonly used in a lot of Unix based systems and is very common in web environments. Legato does have functions that will convert Windows Filetime to Unix time and back (the DateToUnix and UnixToDate functions, respectively) in case you need to switch between the two. Make sure whenever you are doing comparisons or date math operations, you know which type of date-time value you are using.


Legato also provides a way for you to convert date strings into Windows Filetime dwords. The SDK function StringToDate takes a date time string and a format value as parameters and returns a Filetime value. It is pretty good at picking up most common types of date time formats (such as MySQL default string formats, a very common date format), but if you specify the format of the incoming data it helps to ensure a proper conversion. The defined values for formats are:


  Definition   Bitwise   Description
  Modes        
    SD_PARSEMODE   0x0000000F   String Parse Mode Mask
    SD_AMERICAN   0x00000000   String is American (mm/dd/yy)
    SD_EUROPEAN   0x00000001   String is European (dd/mm/yy)
    SD_ISO_8601   0x00000002   String is ISO-8601
  Options        
    SD_PARTIAL   0x00010000   Can be Partially Formatted

 


Of course, if you actually want to display time to a user in an intelligible way, you need to convert from Unix time or Windows Filetime formats to a string value. Legato has a very useful function called the FormatDate function that can take either a Windows Filetime date-time qword or an ISO-8601 formatted date string and convert it into whatever date format you want. The date format output can be a normal ISO-8601 style (ISO-8601 is a common way of writing dates, and more information on it can be found here), or it can be anything specified by a format string. The format string can use the following substitution characters (based on PHP 5.x):


 
  Character   Description   Example returned values
  Day        
    d   Day of the month, 2 digits with leading zeros.   01 to 31
    D   A textual representation of a day, three letters.   Mon through Sun
    j   Day of the month without leading zeros.   1 to 31
    l   A full textual representation of the day of the week.   Sunday through Saturday
    N   ISO-8601 numeric representation of the day of the week.   1 (for Monday) through 7 (for Sunday)
    S   English ordinal suffix for the day of the month, 2 characters.   st, nd, rd or th. Works well with j
    w   Numeric representation of the day of the week.   0 (for Sunday) through 6 (for Saturday)
    z   The day of the year (starting from 0)   0 through 365
  Week        
    W   ISO-8601 week number of year, weeks starting on Monday (not supported).   Example: 42 (the 42nd week in the year)
  Month        
    F   A full textual representation of a month, such as January or March.   January through December
    m   Numeric representation of a month, with leading zeros.   01 through 12
    M   A short textual representation of a month, three letters.   Jan through Dec
    n   Numeric representation of a month, without leading zeros.   1 through 12
    t   Number of days in the given month.   28 through 31
  Year        
    L   Whether it is a leap year.   1 if it is a leap year, 0 otherwise.
    o   ISO-8601 year number. This has the same value as Y (PHP supports the exception that if the ISO week number (W) belongs to the previous or next year, that year is used instead. Legato does not.)   Examples: 1999 or 2003
    Y   A full numeric representation of a year, 4 digits.   Examples: 1999 or 2003
    y   A two digit representation of a year.   Examples: 99 or 03
  Time        
    a   Lowercase Ante meridiem and Post meridiem.   am or pm
    A   Uppercase Ante meridiem and Post meridiem.   AM or PM
    B   Swatch Internet time.   000 through 999
    g   12-hour format of an hour without leading zeros.   1 through 12
    G   24-hour format of an hour without leading zeros.   0 through 23
    h   12-hour format of an hour with leading zeros.   01 through 12
    H   24-hour format of an hour with leading zeros.   00 through 23
    i   Minutes with leading zeros.   00 to 59
    s   Seconds, with leading zeros.   00 through 59
    u   Microseconds.   Example: 654321
  Timezone        
    e   Time zone identifier (not supported).   Examples: UTC, GMT ...
    I   Whether or not the local system is in daylight saving time.   1 if Daylight Saving Time, 0 otherwise.
    O   Difference to Greenwich time (GMT) in hours.   Example: +0200
    P   Difference to Greenwich time (GMT) with colon between hours and minutes.   Example: +02:00
    T   Time zone abbreviation (not supported).   Examples: EST, MDT ...
    Z   Time zone offset in seconds. The offset for time zones west of UTC is always negative, and for those east of UTC is always positive.   -43200 through 50400
  Full Date/Time        
    c   ISO 8601 date (not supported).   2004-02-12T15:19:21+00:00
    r   RFC 2822 formatted date (not supported).   Example: Thu, 21 Dec 2000 16:01:07 +0200
    U   Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) (not supported).   -

 



You can also use one of the predefined formats specified in Legato. Formatting codes can be combined with bitwise operators. Therefore, if you want a mm-dd-yy format but with spaces instead of dashes in the format, you would use the code:


datestring = FormatDate(filetime, DS_DDMMYY | DS_SPACES);

Of course you could replicate this exact style with a custom string format, but this is another way to define the format of the string. The defined formatting codes are:


Definition   Bitwise   Description   Example
Date Modes    
  DS_MMDDYY   0x00000000   mm/dd/yy   06/30/13
  DS_MMDDYYYY   0x00000001   mm/dd/yyyy   06/30/2013
  DS_DDMMYY   0x00000002   dd/mm/yy   30/06/13
  DS_DDMMYYYY   0x00000003   dd/mm/yyyy   30/06/2013
  DS_MMMDDYY   0x00000004   mmm/dd/yy   JUN 30 13
  DS_MMMDDYYYY   0x00000005   mmm/dd/yyyy   JUN 30 2013
  DS_DDMMMYY   0x00000006   dd/mmm/yy   30 JUN 13
  DS_DDMMMYYYY   0x00000007   dd/mmm/yyyy   30 JUN 2013
  DS_YYYYMMDD   0x00000008   yyyy/mm/dd   2013/06/30
  DS_MON_DAY_YEAR   0x00000009   Mon. Day, Year   Jun. 30, 2013
  DS_MONTH_DAY_YEAR   0x0000000A   Month Day, Year   June 30, 2013
  DS_WEEKDAY_MONTH_DAY_YEAR   0x0000000B   Weekday, Month Day, Year
  Sunday, June 30, 2013
Time Mode    
  DS_HHMM_24   0x00000000   hh:mm (24-hour)   23:55
  DS_HHMM_12   0x00000010   hh:mm (12-hour)   11:55 PM
  DS_HHMMSS_24   0x00000020   hh:mm:ss (24-hour)   23:55:30
  DS_HHMMSS_12   0x00000030   hh:mm:ss (12-hour)   11:55:30 PM
Date Delimiters    
  DS_SLASH   0x00000000   Slashes   06/30/2013
  DS_DASH   0x00010000   Dashes   06-30-2013
  DS_SPACES   0x00020000   Spaces   06 30 2013
  DS_SPACESCOMMA   0x00030000   Spaces and Commas   June 30, 2013
  DS_PERIODS   0x00040000   Periods   06.30.2013
Output Mode    
  DS_DATE   0x00000000   Date only   06/30/2013
  DS_TIME   0x01000000   Time only   23:55
  DS_DATE_TIME   0x02000000   Date then time   06/30/2013 23:55
  DS_DATE_AT_TIME   0x03000000   Date at time   06/30/2013 at 23:55
  DS_TIME_DATE   0x04000000   Time then date   23:55 06/30/2013
  DS_DATE_T_TIME   0x05000000   ISO-8601 ™ connector   dateTtime
Case    
  DS_DEFAULT_CASE   0x00000000   Default (all lower case)   june 30 2013
  DS_LOWER   0x10000000   Lower   june 30 2013
  DS_UPPER   0x20000000   Upper   JUNE 30 2013
  DS_INITIAL   0x30000000   Initial capitalization   June 30 2013
Other    
  DS_ISO_8601   0x05010028   ISO-8601 combination   2013-06-30T23:55:30
  DS_NO_ZERO_FILL   0x80000000   No zero filling   6/30/2013
  DS_FILETIME_UTC    0x00000100   Converts as raw UTC   -


In summary, working with dates and times is commonly a part of scripting, and Legato provides multiple powerful tools to make date-time values easy to create, convert from format to format, and display to users.






Steven Horowitz has been working for Novaworks for over five years as a technical expert with a focus on EDGAR HTML and XBRL. Since the creation of the Legato language in 2015, Steven has been developing scripts to improve the GoFiler user experience. He is currently working toward a Bachelor of Sciences in Software Engineering at RIT and MCC.

 


Additional Resources

Novaworks’ Legato Resources

Legato Script Developers LinkedIn Group

Primer: An Introduction to Legato 

Posted by
Steven Horowitz
in Development at 17:07
Trackbacks
Trackback specific URI for this entry

No Trackbacks

Comments
Display comments as (Linear | Threaded)
No comments
Add Comment
Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

 
   
 

Quicksearch

Categories

  • XML Accounting
  • XML AICPA News
  • XML FASB News
  • XML GASB News
  • XML IASB News
  • XML Development
  • XML Events
  • XML FERC
  • XML eForms News
  • XML FERC Filing Help
  • XML Filing Technology
  • XML Information Technology
  • XML Investor Education
  • XML MSRB
  • XML EMMA News
  • XML FDTA
  • XML MSRB Filing Help
  • XML Novaworks News
  • XML GoFiler Online Updates
  • XML GoFiler Updates
  • XML XBRLworks Updates
  • XML SEC
  • XML Corporation Finance
  • XML DERA
  • XML EDGAR News
  • XML Investment Management
  • XML SEC Filing Help
  • XML XBRL
  • XML Data Quality Committee
  • XML GRIP Taxonomy
  • XML IFRS Taxonomy
  • XML US GAAP Taxonomy

Calendar

Back May '25 Forward
Mo Tu We Th Fr Sa Su
Monday, May 19. 2025
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Feeds

  • XML
Sign Up Now
Get SEC news articles and blog posts delivered monthly to your inbox!
Based on the s9y Bulletproof template framework

Compliance

  • FERC
  • EDGAR
  • EMMA

Software

  • GoFiler Suite
  • SEC Exhibit Explorer
  • SEC Extractor
  • XBRLworks
  • Legato Scripting

Company

  • About Novaworks
  • News
  • Site Map
  • Support

Follow Us:

  • LinkedIn
  • YouTube
  • RSS
  • Newsletter
  • © 2024 Novaworks, LLC
  • Privacy
  • Terms of Use
  • Trademarks and Patents
  • Contact Us