Date Format Custom Node

john's Avatar

john

07 May, 2017 12:43 PM

UPDATE: SEE REPLY TO THIS COMMENT...

Frederik,

On April 3, 2014 you made the following entry in a (now closed) discussion:

For the date conversion I've written another node that will make it into NodeBox itself soon. For now, I've attached it here.

I takes an input format and an output format, both in a format you specify. The format uses Java's SimpleDateFormat -- see that page for examples. http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat...

Discussion link: http://support.nodebox.net/discussions/general-discussion/13195-vis...

I've been using your date format.clj custom node in a number of my projects and it's been a big help. This really should be an official NodeBox node.

However, today I ran into a subtle issue that people should be aware of if they use this node. The node itself is fine. The issue is that Java's SimpleDateFormat can be VERY tricky.

I had a series of start and end timestamps that look like this: 2017-01-31 16:58:34

For the input format I had been using YYYY-MM-DD HH:mm:ss

I then calculated the difference in seconds between the two dates by using "u" as the output format and subtracting the two numbers.

But when I looked closely, the difference values were slightly off, usually by only a few seconds.

Looking more closely at the doc you linked to, I realized I should be using yyyy instead of YYYY.

That helped, but a few of the times were still SLIGHTLY off. I thought I was starting to lose my mind until I found this:

http://stackoverflow.com/questions/41177442/uuuu-versus-yyyy-in-dat...

The following input format finally gave me correct values: uuuu-MM-DD HH:mm:ss

By the way, both of those docs say that DD is day in year, while dd is day in month. I interpreted that to mean I should be using dd instead of DD, but NO! That change also introduced a very subtle error.

The moral of the story is that anyone using this custom node to should carefully examine the format strings and play with them until you get them right. In general it appears you should use uuuu instead of yyyy.

If you ever add this node (and I hope you do), you should find a more up-to-date doc or include a reference to this issue in your notes.

John

  1. Support Staff 1 Posted by john on 15 May, 2017 12:24 AM

    john's Avatar

    Frederik, All,

    It turns out that the discrepancies I was having with the date function were not due to improper formats. There is a bug (actually two) in the function itself. I am attaching an updated version which replaces it.

    (You can disregard what I said above about using 'uuuu' instead of 'yyyy' - but my other comments stand: the formats are tricky and it's still a good idea to spot-check the function before relying on it.)

    The bug is revealed when I try to use the "u" format to convert to total seconds so that I can shift dates.

    If I use your node to convert a date in 'yyyy-MM-dd HH:mm:ss' format to 'u', and then use it again to convert 'u' back to 'yyyy-MM-dd HH:mm:ss' I would expect to see the original date.

    Instead what happens is that I get an error: "convert_date No matching method found: valueOf". This is a number formatting issue; the function returns an Integer but expects a Long. When I fix that (either in Clojure or NodeBox) the error goes away, but the resulting date is off by a few seconds (plus or minus less than a minute).

    Here is the relevant section from your Clojure function:

    (defn convert-date [d input-format output-format]
      (let [date-in (if (= input-format "u")
                     (java.util.Date. (* 1000 (Long/valueOf d)))
                      (.parse (java.text.SimpleDateFormat. input-format) d))]
        (if (= output-format "u")
          (Math/round (float (/ (.getTime date-in) 1000)))
          (.format (java.text.SimpleDateFormat. output-format) date-in))))
    

    I made two changes. First, I changed the output to a Long by wrapping the u output in Long/valueOf. Second, I replaced the "float" inside the round with a "double". Here is the updated code:

    (defn convert-date [d input-format output-format]
      (let [date-in (if (= input-format "u")
                     (java.util.Date. (* 1000 (Long/valueOf d)))
                      (.parse (java.text.SimpleDateFormat. input-format) d))]
        (if (= output-format "u")
          (Long/valueOf (Math/round (double (/ (.getTime date-in) 1000))))
          (.format (java.text.SimpleDateFormat. output-format) date-in))))
    

    This seems to do the trick. Updated function attached.

    Frederick, you originally said you would soon add this function to NodeBox as a standard node. I urge you to this as soon as possible. But it you agree with my change I suggest using my updated function instead of your original version.

    Please let me know that you saw this.

    Thanks,

    John

Reply to this discussion

Internal reply

Formatting help / Preview (switch to plain text) No formatting (switch to Markdown)

Attaching KB article:

»

Attached Files

You can attach files up to 10MB

If you don't have an account yet, we need to confirm you're human and not a machine trying to post spam.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac

Recent Discussions

23 Apr, 2024 07:54 PM
19 Apr, 2024 04:41 AM
16 Apr, 2024 06:18 PM
16 Apr, 2024 04:23 AM
08 Apr, 2024 01:28 AM

 

07 Apr, 2024 11:50 PM
05 Apr, 2024 11:47 PM
05 Apr, 2024 12:30 AM
25 Mar, 2024 08:48 PM
14 Mar, 2024 07:40 PM
14 Mar, 2024 07:38 PM