• 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, December 29. 2017

LDC #65: It's Almost The New Year

It’s nearly the day where we all stare at the clocks waiting for the time to strike midnight. I’m talking, of course, about New Year’s Eve. A new year means new beginnings and new adventures. So to count us down to midnight I created a Legato script to inform you how long it is until the new year.

To do this we’re going to create a custom dialog, show it to the user, and then update the dialog every half second to keep the timing fairly close without putting too much strain on our computer. We will use some of the date functions to get the current time, get the time at midnight on New Years Eve, compare the two, and get the amount of time remaining.


Without further ado, let’s get into it.


string newyear;
qword nwyr;
qword now;
int nowunix;
int newunix;
string timeleft;
string timeleftarray[];
int secondsleft;

int days;
int hours;
int minutes;
int seconds;

string daylabel;
string hourlabel;
string minutelabel;
string secondlabel;

int updateTime() {

    now = GetLocalTime();
    nowunix = DateToUnix(now);
    secondsleft = newunix-nowunix;
    timeleft = SecondsToTime(secondsleft);
    
    timeleftarray = ExplodeString(timeleft, ":");

    hours = DecimalToInteger(timeleftarray[0]);
    minutes = DecimalToInteger(timeleftarray[1]);
    seconds = DecimalToInteger(timeleftarray[2]);
    days = hours/24;
    hours = hours%24;
    if (days == 1) {
      daylabel = "day";
      }
    else {
      daylabel = "days";
      }
    if (hours == 1) {
      hourlabel = "hour";
      }
    else {
      hourlabel = "hours";
      }
    if (minutes == 1) {
      minutelabel = "minute";
      }
    else {
      minutelabel = "minutes";
      }
    if (seconds == 1) {
      secondlabel = "second";
      }
    else {
      secondlabel = "seconds";
      }
    return ERROR_NONE;
    }

int main() {
    newyear = "2018-01-01T00:00:00";
    nwyr = StringToDate(newyear, 2);
    newunix = DateToUnix(nwyr);
    updateTime();
    DialogBox("TimeLeftDlg", "TL_");
    return ERROR_NONE;
    }

int TL_load() {
    DialogSetTimer(500, 1);
    EditSetText(101, FormatString("%d %s, %02d %s, %02d %s, %02d %s left", days, daylabel, hours, hourlabel, minutes, minutelabel, seconds, secondlabel));
    }
    
int TL_timer(int id) {
    updateTime();
    EditSetText(101, FormatString("%d %s, %02d %s, %02d %s, %02d %s left", days, daylabel, hours, hourlabel, minutes, minutelabel, seconds, secondlabel));
    }
    
#resource
TimeLeftDlg DIALOG 0, 0, 180, 44
STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "It's Almost The New Year!"
FONT 8, "MS Sans Serif"
{
 CONTROL "", 101, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 6, 8, 140, 8, 0
 CONTROL "until the New Year!", 102, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 6, 16, 160, 8, 0
 CONTROL "Stop", IDCANCEL, "BUTTON", BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 126, 24, 45, 12
 }
#endresource

Please note that if you’re using this script exactly as written it will count up after the new year.


So the first thing that we do is create a whole bunch of global variables. These variables will be used throughout the script to keep track of how much time is left and also keep track of the labels to print everything out in a more human friendly form. These variables are purposefully left global so that they can be updated in one function and then used in another without having to pass all of variables around.


string newyear;
qword nwyr;
qword now;
int nowunix;
int newunix;
string timeleft;
string timeleftarray[];
int secondsleft;

int days;
int hours;
int minutes;
int seconds;

string daylabel;
string hourlabel;
string minutelabel;
string secondlabel;

Next we will create a function to do the calculations and update the variables to the current values. We’ll also do the logic to update the textual values. I’ll explain this section in detail below.


int updateTime() {

    now = GetLocalTime();
    nowunix = DateToUnix(now);
    secondsleft = newunix-nowunix;
    timeleft = SecondsToTime(secondsleft);
    
    timeleftarray = ExplodeString(timeleft, ":");

    hours = DecimalToInteger(timeleftarray[0]);
    minutes = DecimalToInteger(timeleftarray[1]);
    seconds = DecimalToInteger(timeleftarray[2]);
    days = hours/24;
    hours = hours%24;
    if (days == 1) {
      daylabel = "day";
      }
    else {
      daylabel = "days";
      }
    if (hours == 1) {
      hourlabel = "hour";
      }
    else {
      hourlabel = "hours";
      }
    if (minutes == 1) {
      minutelabel = "minute";
      }
    else {
      minutelabel = "minutes";
      }
    if (seconds == 1) {
      secondlabel = "second";
      }
    else {
      secondlabel = "seconds";
      }
    return ERROR_NONE;
}

The first thing that we have to do is get the current time. GetLocalTime will give us the current time in the current timezone as a QWORD. We need to find a way to easily compare times, and the easiest way to do that in general is to get the Unix epoch equivalent, or the number of seconds since January 1st, 1970. We then take the Unix time of the new year and subtract the current time from that, giving us the number of seconds between the dates. We then convert the time back into a QWORD to use with other Legato functions. We use SecondsToTime to convert seconds into a string that is in “Hours:Minutes:Seconds” format, and then explode the result into an array on the colons. This gives us an array with those three values. We take the first and store it as hours, the second as minutes, and third as seconds. Finally we get the number of days by taking the number of hours and dividing by 24, while then using the modulus operation to get the remaining hours in the day. We could work entirely in Unix time, but we’re using Legato functions here to make the code easier to understand.


Finally the last thing to do is to check whether we have to make our label singular by seeing if any of these values is 1. If it is, the label is singular, otherwise the label is made to be plural.


The function that we just made will be called every single update. Now let’s look at what runs when we start the script.


int main() {
    newyear = "2018-01-01T00:00:00";
    nwyr = StringToDate(newyear, 2);
    newunix = DateToUnix(nwyr);
    updateTime();
    DialogBox("TimeLeftDlg", "TL_");
    return ERROR_NONE;
    }

Here we define the new year as midnight on the 1st of January 2018, convert it to a date format, then convert it to unix time. We use that value in the updateTime function. We then call the function we just went through, open our dialog box, and return.


int TL_load() {
    DialogSetTimer(500, 1);
    EditSetText(101, FormatString("%d %s, %02d %s, %02d %s, %02d %s left", days, daylabel, hours, hourlabel, minutes, minutelabel, seconds, secondlabel));
    }
    
int TL_timer(int id) {
    updateTime();
    EditSetText(101, FormatString("%d %s, %02d %s, %02d %s, %02d %s left", days, daylabel, hours, hourlabel, minutes, minutelabel, seconds, secondlabel));
    }

These two functions are pretty similar. One is called when the dialog first opens, the other is called when the timer ticks. The load function starts the timer running and then updates the text in the dialog to the values we just calculated in the updateTime function. The timer function runs the updateTime function and then updates the text in the dialog. That’s all we have to do with the dialog, as the “Stop” button uses IDCANCEL and will close the dialog, causing the main function to continue and finish.


#resource
TimeLeftDlg DIALOG 0, 0, 180, 44
STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "It's Almost The New Year!"
FONT 8, "MS Sans Serif"
{
 CONTROL "", 101, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 6, 8, 140, 8, 0
 CONTROL "until the New Year!", 102, "static", SS_LEFT | WS_CHILD | WS_VISIBLE, 6, 16, 160, 8, 0
 CONTROL "Stop", IDCANCEL, "BUTTON", BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 126, 24, 45, 12
 }
#endresource

Finally we have the resource for the dialog. I’ve created a small dialog with the title “It’s Almost The New Year!”, two small text controls, and a cancel button. The first static string control is left blank as that is the value that we update each time the timer ticks.


This script can be updated or extended fairly easily. You can change the day that you are counting down to, or even add in an initial dialog to choose the date dynamically.


To end the year, I’ve created a small script that will help us count down to ringing in the new year. We use some of Legato’s date functions to compare the dates between now and midnight on New Years Eve, and then we use a dialog to display these results to our user.


From all of us here at Novaworks, have a wonderful New Year and we hope that your 2018 will bring you many new experiences and excitement.


 


Joshua Kwiatkowski is a developer at Novaworks, primarily working on Novaworks’ cloud-based solution, GoFiler Online. He is a graduate of the Rochester Institute of Technology with a Bachelor of Science degree in Game Design and Development. He has been with the company since 2013.

Additional Resources

Novaworks’ Legato Resources

Legato Script Developers LinkedIn Group

Primer: An Introduction to Legato 



Posted by
Joshua Kwiatkowski
in Development at 17:56
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
Sunday, May 18. 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