RegEx to split formatting string in JavaScript - javascript

I am using a JS date library which has a simple asString() formatting syntax e.g. dd mmm yyyy produces 01 Jan 1970.
Unfortunately should the month happen to contain a letter that appears in the formatting string it can go wrong, e.g. `Date('2014-09-01').asString('dd mmm yyyy') = 01 Septe9ber 2014'
To solve this is quite simple; alter the asString() method to use the format '[dd] [mmm] [yyyy]' instead. However this comes from a global format string used by other methods. The only method that needs the square brackets is the asString method.
So my ideal solution is to simply add a function in that method which replaces any of the following strings within the format string:
formats=['yyyy','yy','mmmm','mmm','mm','m','dddd','ddd','dd','d','hh','min','ss'];
With itself surrounded by []
dd/mm/yyyy => [dd]/[mm]/[yyyy]
Unfortunately the RegEx is proving to be complex - simply looping through each item results in [[d][d]]/[[m][m]]/[[yy][yy]].
So I'd like help writing this RegEx. If it can't be done please say so - I'm not interested in using new libraries as a solution but would consider solutions which solved the problem in a different way within the current asString method (i.e. no breaking changes)

This should do:
var regex = /(min|y+|m+|d+|h+|s+)/g,
newString = format.replace(regex,'[$1]');
Tested with the format "dd/mm/yyyy", resulted in "[dd]/[mm]/[yyyy]"

Related

Can you get the date format pattern from a date string with Moment.js

I want to be able to get the date format string from a date string in JavaScript.
I also am using Moment.js as well if this can be achieved using this.
As an example if I have a string such as
2019-01-01 15:00:00
I'd like something like this returned
YYYY-MM-DD HH:mm:ss
I've searched the documentation but cannot find any answers to this.
You can use Parse Date Format plug-in:
This plugin extracts the format of a date/time string.
Here a live example:
const input = "2019-01-01 15:00:00"
const dateFormat = moment.parseFormat(input);
console.log(dateFormat);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://gr2m.github.io/moment-parseformat/moment-parseformat.js"></script>
Edit after #VLAZ comment, parseFormat has the preferredOrder option:
parseFormat tries to figure out the the order of day/month/year by itself if it finds 3 numbers separated by ., - or /. But if it can't, it will fallback to preferredOrder, which can either be set as an object to differentiate by separator, or as a simple string.

datetime Regular Expressions pattern to match yyyy-MM-dd hh:mm:ss format

Im trying to create regex pattern in javascript to validate datetime format yyyy-MM-dd hh:mm:ss
/([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9]) ([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(([\-\+]([0-1][0-9])\:00))/
here is an example on jsfiddle
but its not working when i test it against this date time 2017-08-31 01:22:34
can anybody help me to know whats wrong in my pattern
Thank you
It's because the pattern currently requires, rather than makes optional, the timezone modifier, which isn't present in the example date you gave.
Change the last part to:
( ([\-\+]([0-1][0-9])\:00))?
Also:
your hours sub-group is matching 0-59 rather than 0-23.
you're escaping a number of things you don't need to, e.g. : and -
the pattern allows for invalid dates e.g. 39 as a day.
Revision:
/^([0-2][0-9]{3})\-(0[1-9]|1[0-2])\-([0-2][0-9]|3[0-1]) ([0-1][0-9]|2[0-3]):([0-5][0-9])\:([0-5][0-9])( ([\-\+]([0-1][0-9])\:00))?$/
Note this will not account for invlaid dates in certain months e.g. 30th February. That means either making the pattern more complicated or using something better suited than REGEX for date validation.
It's because of the last part which should be optional (([\-\+]([0-1][0-9])\:00))?
Here is a demo
var a = /([0-2][0-9]{3})-([0-1][0-9])-([0-3][0-9]) ([0-5][0-9]):([0-5][0-9]):([0-5][0-9])(([\-\+]([0-1][0-9])\:00))?/;
console.log('2017-08-31 01:22:34'.match(a))
BTW, you don't have to escape :. - should be escaped only when used inside brackets []
In java, we can use like below and also you can take this pattern for javascript
private static Pattern DATE_PATTERN = Pattern.compile(".*?\[0-9\]{4}-(0\[1-9\]|1\[0-2\])-(0\[1-9\]|\[1-2\]\[0-9\]|3\[0-1\]) (2\[0-3\]|\[01\]\[0-9\]):\[0-5\]\[0-9\]:\[0-5\]\[0-9\]");
public void test() {
if(!DATE_PATTERN.matcher(line.trim()).matches()) {
//code here
}
}
If you want to check only date then remove *? from the pattern

js Date too much clever behavior

I encounter problem when parsing date via native JS Date object.
new Date("I'm really clever date 8745")
This expression returns valid Date which was pretty shocking for me. How to prevent this special behavior ?
EDIT: Date interprets last number as year ...
EDIT: Chrome, version (48.0.2564.116)
EDIT: Expected format is "2016-03-20T18:05:53.485Z" (JSON stringify)
if you intend to "match" any valid date (eg. christmas...), it is far from simple. if istead you want to allow only some format type, i'll go with regexp. here a simple not very extended example:
function isprobablyavaliddate(str){
var allowed = /\d{4}[\\\/-]{1}\d{2}[\\\/-]{1}\d{2}/
//example allowed date formats: yyyy-mm-dd, yyyy/mm/dd
return allowed.test(str)
}
var testString = "I'm really clever date 8745"
//catch valid string before doing anything with a date...
if ( isprobablyavaliddate(testString) ) mydate = new Date(testString)
else ...
for your valid format requested in your edit: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z/ (the ^ is for match initial character)
I used regex for testing if string is valid ISO date.
/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/;
Works perfectly.

Are problems in achieving find the separator location in javascript

I have a question.
I was wondering how I can find the separator location.
Or have the date in the format DD / MM / YYYY without having to force the slash.
Any suggestions?
Thanks
You can use indexOf or lastIndexOf to find your seperator locations. If it's just a matter of formatting the date then take a look at some of the date libraries available out there.
Here are just a few:
moments.js
dates.js
xdate.js
there are many more, just G* search "javascript date library"
I was wondering if there is any function or method that I return the system date in the format:
10/12/2012 or 12/10/2012 or last 10:12:2012
but not manually enter the slash, colon or dash.

How to parse arbitrary dates with datejs parseExact

I want to parse a date in this format '11h04 31/05/2011' and other arbitrary formats using datejs, I tried:
Date.parseExact("11h04 31/05/2011", "HH'h'mm dd/MM/yyyy")
and
Date.parseExact("11h04 31/05/2011", "HH\hmm dd/MM/yyyy")
without success.
Does anyone knows the exact format/specification of parseExact or how to parse this (and others) arbitrary formats?
In java i would do this:
SimpleDateFormat sdf = new SimpleDateFormat("HH'h'mm dd/MM/yyyy");
sdf.parse(date);
P.S.: yeah, I know I can use a regex to split the string and then parse, but I want to know how to parse it with parseExact.
Thanks in advance.
Does anyone knows the exact format/specification of parseExact
Here is a link to the date.js format specifiers used by date.js and parseExact
http://code.google.com/p/datejs/wiki/FormatSpecifiers#CUSTOM_DATE_AND_TIME_FORMAT_SPECIFIERS
I can't find any way to trick the parseExact method into thinking the formatString doesn't contain a literal h between HH and mm. Tried \u0068, \0x68, no luck.
I think your best bet is
var date = "11h04 31/05/2011";
Date.parseExact(date.replace("h",""),"HHmm dd/MM/yyyy")

Categories