12

Globalize.js allows you to parse a date string based on the current culture applied

var date = Globalize.parseDate("17/07/2013"); //Wed Jul 17 00:00:00 PDT 2013

What I would like to do is parse a DateTime. The javascript Date object handles this, I'm surprised the Globalize.js library doesn't.

var date = new Date("07/17/2013 11:55 pm"); //Wed Jul 17 23:55:00 PDT 2013
var date = Globalize.parseDate("07/17/2013 11:55 pm"); //null

Am I missing something? I'm leaning towards parsing the time portion myself. Is there another library that extends Globalize.js that provides this kind of functionality? I've looked around but haven't found much.

UPDATE w/ accepted answer

You can parse the date if you know the format that the date is in.

    var date = Globalize.parseDate("17/07/2013 11:55 pm", "MM/dd/yyyy hh:mm tt"); 
    //date = null

In my example the date will be null because it expects the time period to be in the format of a.m or p.m.. Once I changed that I was able to parse a datetime.

   var date = Globalize.parseDate("17/07/2013 11:55 p.m.", "MM/dd/yyyy hh:mm tt"); 
   //date = Wed Jul 17 23:55:00 PDT 2013

Note: This is only applicable to the deprecated Globalize 0.x.

Note 2: Passing a hardcoded pattern is NOT an i18n recommendation.

Rafael Xavier
  • 2,840
  • 27
  • 34
Kevin
  • 2,752
  • 1
  • 24
  • 46
  • Passing a hardcoded pattern is NOT an i18n recommendation. You should use skeleton instead (Globalize 1.x) http://stackoverflow.com/a/30237866/798133. – Rafael Xavier Feb 03 '17 at 15:28

4 Answers4

12

If you know the pattern you are using:

var date = Globalize.parseDate("07/17/2013 11:55 pm", "MM/dd/yyyy hh:mm tt");

If you don't know the pattern:

var date = Globalize.parseDate("07/17/2013 11:55 pm", Globalize.culture().calendar.patterns.d + " " + Globalize.culture().calendar.patterns.t)

The line above is assuming current culture, if you need it for other culture or if you haven't established the local culture by calling Globalize.culture("") then just specify the culture on culture().

I just ran on this scenario a few minutes ago, and found this solution, the latest it is messy, I hope there is a cleaner way to do this.

Note: This is only applicable to the deprecated Globalize 0.x.

Note 2: Passing a hardcoded pattern is NOT an i18n recommendation.

Rafael Xavier
  • 2,840
  • 27
  • 34
Raciel R.
  • 2,136
  • 20
  • 27
  • I just wanted to parse time, so i used Globalize.parseDate("11:55 pm", Globalize.culture().calendar.patterns.t). But i got null as a result. Any advice? – MARKAND Bhatt Jul 31 '14 at 09:35
  • @MARKANDBhatt just prepend a valid date string to your time string and call Globalize.parseDate – Mark Ibanez May 07 '15 at 04:35
  • 2
    I think this solution would be applicable on the `globalize` version 0.x, but not for the 1.x version of the library – Hakan Fıstık Feb 03 '17 at 07:29
3

I would look into moment.js, with it you can do

d = moment("17/07/2013 11:55 pm" , "DD/MM/YYYY HH:mm a"); // parsed as 11:55pm local time
d = d.toDate(); //get it as a native js date object

Unless you specify a timezone offset, parsing a string will create a date in the current users timezone.

dave
  • 62,300
  • 5
  • 72
  • 93
  • 2
    I find moment.js very usefull when it comes to date/time manipulation. However in the scenarios I deal with most of the times the culture is defined either by the user or the browser, so I don't know the right pattern before hand. I usually end up with something like: moment("16/07/2012 12:45", moment().lang()._longDateFormat.L + " " + moment().lang()._longDateFormat.LT).toDate() which is similar to my answer below using Globalize. Do you know if there is a shorter way? – Raciel R. Jul 19 '13 at 22:36
3

Globalize 1.x is based on CLDR and has a different API now. Follow the new code to accomplish what you need:

Globalize("en").parseDate("5/14/2015, 9:47 AM", {skeleton: "yMdhm"});
// > Thu May 14 2015 09:47:00 GMT-0300 (BRT)

More information and examples.
More information on how to load CLDR.
Notes on how to use CLDR patterns

Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
Rafael Xavier
  • 2,840
  • 27
  • 34
  • How would you set a different separator rather than comma? yMdHm enforces comma (,) as the separator whereas I need space. – Jimit Oct 17 '17 at 15:36
  • Globalize isn't lenient in that regard, i.e., to ignore a literal or to accept any literal. (Note comma and space is a literal defined by the format). One hacky solution would be to modify CLDR data before you feed it on Globalize. Alternatively, can you use a guided input like https://github.com/rxaviers/react-date-input? – Rafael Xavier Oct 17 '17 at 20:15
  • I'm trying this approach using the skeleton, but it does not parse: Globalize("nb").parseDate("05.09.2018 12:00",{skeleton: "yMdHm"}) // yMd is d.M.y and Hm is HH:mm according to ca-gregorian.json – Vincent Sep 07 '18 at 07:02
1

The accepted answer means that all date time fields must have a full date and time. However, it is more than acceptable that some fields will have just a date. So I modified the globalize.culture.en-AU.js to add my custom pattern.

Globalize.addCultureInfo( "en-AU", "default", {
    name: "en-AU",
    englishName: "English (Australia)",
    nativeName: "English (Australia)",
    numberFormat: {
        currency: {
            pattern: ["-$n","$n"]
        }
    },
    calendars: {
        standard: {
            firstDay: 1,
            patterns: {
                d: "d/MM/yyyy",
                D: "dddd, d MMMM yyyy",
                f: "dddd, d MMMM yyyy h:mm tt",
                F: "dddd, d MMMM yyyy h:mm:ss tt",
                M: "dd MMMM",
                Y: "MMMM yyyy",
                Z: "dd/MM/yyyy hh:mm:ss tt" // This is a custom one for our specifications.
            }
        }
    }
});

It's not the best solution by modifying it, but for my and most others purpose they won't be upgrading the Globalization.js from version 0.x to 1.x anytime soon.

This answer means you can have a date with time, and just a date field together in the same project and on the same page.

Rhys Stephens
  • 889
  • 3
  • 20
  • 36