The javascript Date.toLocaleDateString() is silly.
What I need is a function that allows me to simplify the date according to preference.
It would be nice if there were a function which would read the browser date formats (plural) and take an optional parameter telling it which format to use.
I'll explain:
"MM/DD/YYYY" works great for the US and anyone willing to put up with them/us.
"DD/MM/YYYY" is the most common format for people interested in a short simple date format.
"Weekday, Month DayOfMonth, Year" is only useful if you want a super-long and language-dependent output.
I could use this:
var s = "/";
if(locale=='us')
var dateString = Date.getDate()+s+Date.getDay()+s+Date.getFullYear();
else
var dateString = Date.getDay()+s+Date.getDate()+s+Date.getFullYear();
But I'm looking for a more elegant solution that will allow me to store a date mask or format string so people can change the way their dates are displayed according to their own tastes. (Even the super-long language-dependent one if they like it enough.)
Should I re-prototype the Date.toString() method to interpret parameters? Is there a better way?
You can use DateTimeFormat Api.
var now = new Date(0)
console.log(new Intl.DateTimeFormat('en-US').format(now)); //12/31/1969
console.log(new Intl.DateTimeFormat('en-GB').format(now)); //31/12/1969
See this link for Mozilla documentation:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
PROS:
you don't have to add more libraries to you project, increasing the
bundle size.
you don't have to worry about browser support, because almost every browser supports it. https://caniuse.com/#search=intl
PS: if you don't care about bundle size and you want something more "user friendly" and easy to use see moment.js or luxon, they are both great libraries for date operations.
I ran into a very powerful library that takes care of dates and generic formatting:
http://blog.stevenlevithan.com/archives/date-time-format
(Wrong link)
http://jawe.net/wiki/dev/jsdateformat/home
Is pretty powerful and configurable. (It supports java-style formats that I need, such as the "MEDIUM" date format)
Moment appears to be useful and feature-full (just no Medium format): https://github.com/timrwood/moment
Related
I've started using momentJs in an Angular/Typescript project. (Included incase it's relevant in any way although I very much doubt it)
In the run method of my module I call
moment.locale(window.navigator.language);
which correctly sets the locale to en-GB in my instance. Further down the line I use moment to parse a GB time.
when doing the following:
var mom = moment("24/11/2015 00:00:00");
for example. This populates a new moment object using the defaults set on the moment global (If i understand how it should work correctly). moms date is set to 2016-12-11T00:00:00.000Z. This clearly means it's parsed the given string in en-US instead of en-GB which was set via Locale in a default setting prior to this call. Is there anything I've missed in configuration/setup of moment which would make this not work?
I've also inspected the _locale property of my variable. mom._locale is set to en-gb and I can see the L,LL,LLL etc etc formats are all en-GB formatted values (as they should be).
running mom.toDate(); unsurprizingly returns the 2016 date stored internally by the moment object.
Some misc information I forgot to include:
I am using the latest release of momentjs from NuGet (Version 2.10.6 at time of writing) and I've included moment-with-locales.js in my HTML
Using any recent version of MomentJS, you should see why in the console:
Deprecation warning: moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.
Unless you specify a format string, MomentJS relies on the Date object's parsing, and unfortunately, regardless of locale the Date object will, with a string using /, assume U.S. format. One of the many, many things that aren't quite right with Date.
You'll need to use a format string, or supply the string in the simplified ISO-8601 format used by Date. From Parse > String:
When creating a moment from a string, we first check if the string matches known ISO 8601 formats, then fall back to new Date(string) if a known format is not found.
var day = moment("1995-12-25");
Warning: Browser support for parsing strings is inconsistent. Because there is no specification on which formats should be supported, what works in some browsers will not work in other browsers.
For consistent results parsing anything other than ISO 8601 strings, you should use String + Format.
So I got around this by fetching the locale data from moment and just passing it into the format parameter. Considering the example input of "24/11/2015 00:00:00" I would structure my format as below:
var format = moment.localeData().longDateFormat('L') + " " + moment.localeData().longDateFormat("LTS");
this generates the format mask of "DD/MM/YYYY HH:mm:ss".
You can mix and match whatever formats you want and this will be locale specific to whatever you set moment.locale("") to be (presuming you have the locale information setup in moment already)
This is a crazy workaround and I'm surprised that moment doesn't presume locale information as default when parsing. TJCrowder has raised an issue on Github with the moment guys which I suggest anyone who cares should comment on. https://github.com/moment/moment/issues/2770
You're probably better off passing the format to moment directly and validating the string before hand. This will ultimately reduce the amount of debugging you'll need to do and get you up and running straight away.
var mom = moment("24/11/2015 00:00:00", "DD/MM/YYYY HH:mm:ss");
You could try the new(ish) Intl API but browser support is limited (IE11+), so I would recommend having a user select the month in a dropdown or something to force them to input a certain way.
Given a text field, I want to have a suitable placeholder. A typical placeholder will be something like: "mm/dd/yyyy".
However, I would like to use locale-aware dates using moment.js.
This means that I will be specifying "l" as the moment.js date format, howe do I determine the date format that moment.js will be using in this case?
The user will not understand what "l" means, so using this value in the placeholder text makes very little sense.
Specifically, I am hoping to be able to access something like moment's internal "defaultLongDateFormat". (Though that is merely a default - moment.js probably updates it or has some other mapping at runtime for locale-aware date formats - I would like to access that mapping.)
EDIT:
There are multiple downvotes (who aren't explaining why they're downvoting it).
I think this is because they arent' understanding the question, so here are some examples:
I want a function such that:
getFormat("l") -> "mm/dd/yyyy", or equivalent for the US locales.
getFormat("l") -> "dd/mm/yyyy", or equivalent, for the AU locales.
I do not want to format a given date, or to parse a given date - I merely want to determine it's user-friendly format given an arbitruary moment.js format, specifically, for 'l'.
I don't think it's exposed nicely, but if the browser has its language configured correctly you can do something like this:
var lang = navigator.languages ? navigator.languages : navigator.language;
moment().locale(lang).localeData()._longDateFormat['L']
Languages behave slightly differently depending on which browser you're using, so don't know how reliable this is.
Follow up to Adam R's answer:
Seems to have been exposed by now:
localeData.longDateFormat(dateFormat);
returns the full format of abbreviated date-time formats LT, L, LL and so on
(source: http://momentjs.com/docs/)
Get the currently used locale data by moment.localeData()
In Javascript I need to work with the concepts of date, time and "date and time " without referring to a particular point in time. This is exactly the same semantics that joda time's LocalDate and LocalTime provide in Java. I've been briefly looking at Date.js and moment.js, but both libraries seem to build on the Date object, which represents a point in time. Is there any javascript library that provides what I need?
Use case:
There is a model entity -a coupon- which has an expiration date (joda time's LocalDate). I want to compare that date with today's date, so I need a representation of today's date (actually a string in yyyy-mm-dd format would do). I know that today's date, and hence the result of the comparison too, will depend on the timezone settings of the browser's but that's not a problem.
I've started a few times on a JavaScript library with similar API to Noda Time / Joda Time / Java 8. I definitely see value in that. However, there's nothing out there as of yet, as far as I know. There are other reasons that make the Date object less than ideal. I'll try to remember to update this post when/if I ever get a new library off the ground, or if I learn of one created by someone else.
In the mean time, the easiest thing would be to use moment.js:
var expDateString = "2015-06-30";
var exp = moment(expDateString, "YYYY-MM-DD");
var now = moment();
if (exp.isAfter(now))
// expired
else
// valid
You could also do this with plain JavaScript, but there are some gotchas with parsing behavior. Moment is easier.
I'm using a date picker built in to my device and it returns the date in format YYYY/MM/DD
and returns the time in format HH:MM 24 hours.
The overall returned string is YYYY/MM/DDT/HH/MM
T being the separator.
What is the best way to validate this so that it matches the format YYYY/MM/DD/T/HH/MM
Regex ? Does JavaScript have validation for date/time built it even if i have to split at T so i have the date and time in separate variables?
Whats the best way/algorithm to do this aswell preformance wise?
If i split my varible in to array like...
["YYYY/MM/DD","HH:MM"]
Is there a regex or js function that validates this best? Preformance is key.
Thanks
I wouldn't be worried about performance, you're not going to be doing this hundreds of thousands of times in a tight loop, presumably.
A regex is a good way to do it, and will be easy to write; if you create the regex once and reuse it, it should perform well too.
Assuming your example of the format is a typo and you meant YYYY/MM/DDTHH:MM, a modern JavaScript engine should also support using that string as the argument to new Date(...) provided you change the / to - (which you can readily do via String#replace). That's because it fits the pared-down ISO-8601 format defined as part of ES5. But older engines (IE8 and earlier, for instance) may not support it, you'd have to test on the browsers you intend to support. But if it's really YYYY/MM/DDT/HH/MM, ignore this paragraph.
I'm including the date.js library in my site because I need its functionality.
I have just realized, though, that the standard Javascript parse() method is overwritten by it.
I'm trying to build a line chart in Highcharts, and the data series wants the first element to be be in milliseconds (their demos show them using the Date.UTC() method to achieve this, but my data is returned in a different format).
Short of doing a bunch of string manipulation to put my data into a format that Date.UTC will recognize, is there another way of getting the standard Javascript parse() functionality while date.js is loaded?
I know this isn't a direct solution to your problem, but it may help anyway.
If you want a fully featured date library that doesn't modify the native Date object, I wrote one called Moment.js.
It provides a lot of the things that DateJS provides (formatting, parsing, manipulation, timeago, i18n, etc), but it's smaller, faster, and doesn't ruin the native date prototype.
https://github.com/timrwood/moment
Nope, this is the intended design of date.js. It adds to the "prototype" of the Date object. Some people hate that, some people like it - but you've uncovered one of the drawbacks of this design.
You can tell Highcharts to not use UTC date:
Highcharts.setOptions({
global: {
useUTC: false
}
});
You should do this before you create the chart. Then you won't have to worry about converting your dates to UTC, it will be easier.
after I asked the question, I went ahead and did it this way:
d = Date.parse(data);
y = d.getFullYear();
m = d.getMonth();
d = d.getDate();
dUTC = Date.UTC(y, m, d);
but will now try your suggestions.