Skip to content

Instantly share code, notes, and snippets.

@Pamblam
Last active April 5, 2018 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pamblam/4d33935d712903da10c7366c20157d21 to your computer and use it in GitHub Desktop.
Save Pamblam/4d33935d712903da10c7366c20157d21 to your computer and use it in GitHub Desktop.
/**
* Format a date using PHP date shorthand
* @param {Date} date - A Javascript Date object
* @param {String} format - The format of the outputted date
* @returns {String} - The formatted date
*/
function formatDate(date, format) {
if (isNaN(date.getTime())) return "Invalid Date";
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var buffer = [];
for(var i=0; i<format.length; i++){
switch(format[i]){
// If the current char is a "\" then skip it and add then next literal char
case "\\": buffer.push(format[++i]); break;
// Symbols that represent numbers
case "Y": buffer.push("" + date.getFullYear()); break;
case "y": buffer.push(("" + date.getFullYear()).substring(2)); break;
case "m": buffer.push(("0" + (date.getMonth() + 1)).substr(-2, 2)); break;
case "n": buffer.push("" + (date.getMonth() + 1)); break;
case "t": buffer.push("" + new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate()); break;
case "d": buffer.push(("0" + date.getDate()).substr(-2, 2)); break;
case "j": buffer.push(date.getDate() + ""); break;
case "w": buffer.push(date.getDay()); break;
case "g": buffer.push("" + (date.getHours() > 12 ? date.getHours() - 12 : date.getHours())); break;
case "G": buffer.push("" + (date.getHours())); break;
case "h": buffer.push(("0" + (date.getHours() > 12 ? date.getHours() - 12 : date.getHours())).substr(-2, 2)); break;
case "H": buffer.push(("0" + (date.getHours()+"")).substr(-2, 2)); break;
case "i": buffer.push(("0" + date.getMinutes()).substr(-2, 2)); break;
case "s": buffer.push(("0" + date.getSeconds()).substr(-2, 2)); break;
case "N": buffer.push(date.getDay()==0?7:date.getDay()); break;
case "L": buffer.push((date.getFullYear() % 4 == 0 && date.getFullYear() % 100 != 0) || date.getFullYear() % 400 == 0 ? "1" : "0"); break;
case "o": buffer.push(date.getMonth()==0&&date.getDate()<6&&date.getDay()<4?date.getFullYear()-1:date.getFullYear()); break;
case "B": buffer.push(Math.floor((((date.getUTCHours() + 1) % 24) + date.getUTCMinutes() / 60 + date.getUTCSeconds() / 3600) * 1000 / 24)); break;
case "v": buffer.push((date.getTime()+"").substr(-3)); break;
case "Z": buffer.push(date.getTimezoneOffset()*60); break;
case "U": buffer.push(Math.floor(date.getTime()/1000)); break;
// Symbols that represent text
case "a": buffer.push(date.getHours() > 11 ? "pm" : "am"); break;
case "A": buffer.push(date.getHours() > 11 ? "PM" : "AM"); break;
case "l": buffer.push(days[date.getDay()]); break;
case "D": buffer.push(days[date.getDay()].substr(0, 3)); break;
case "F": buffer.push(months[date.getMonth()]); break;
case "M": buffer.push(months[date.getMonth()].substring(0, 3)); break;
case "c": buffer.push(date.toISOString()); break;
// Ordinal suffix
case "S":
var suffix = false;
var ones = buffer[buffer.length-1].toString()[1];
var tens = buffer[buffer.length-1].toString()[0];
if(undefined === ones){
ones = tens;
tens = null;
}
if(ones == "1") suffix = "st";
if(ones == "2") suffix = "nd";
if(ones == "3") suffix = "rd";
if(tens == "1" || !suffix) suffix = "th";
buffer.push(suffix);
break;
// ISO-8601 Week number
case "W":
var startDate = new Date(date.getFullYear(), 0);
var endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
while(endDate.getDay() < 6) endDate.setDate(endDate.getDate()+1);
endDate = endDate.getTime();
var weekNo = 0;
while(startDate.getTime() < endDate){
if(startDate.getDay() == 4) weekNo++;
startDate.setDate(startDate.getDate()+1);
}
buffer.push(weekNo);
break;
// Day of the year
case "z":
var startDate = new Date(date.getFullYear(), 0, 1, 0, 0, 0, 0);
var dayNo = 0;
while(startDate.getTime() < date.getTime()){
dayNo++;
startDate.setDate(startDate.getDate()+1);
}
buffer.push(dayNo);
break;
default: buffer.push(format[i]); break;
}
}
return buffer.join('');
}

JS Date Formatter

Format Javascript dates using a subset of the PHP Date shorthand.

Ex: var date = formatDate(new Date(), 'l, F j g:i A');

You could put it on the Date object for ease of use...

Date.prototype.format = function(format){
    return formatDate(this, format);
};

Ex: var date = new Date().format('m/d/y g:i:s a');

Demo here

The following characters are recognized in the format parameter string:

format character Description Example returned values
Day -- --
d Day of the month, 2 digits with leading zeros 01 to 31
D A textual representation of a day, three letters Mon through Sun
j Day of the month without leading zeros 1 to 31
l (lowercase 'L') A full textual representation of the day of the week Sunday through Saturday
N ISO-8601 numeric representation of the day of the week 1 (for Monday) through 7 (for Sunday)
S English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
w Numeric representation of the day of the week 0 (for Sunday) through 6 (for Saturday)
z The day of the year (starting from 0) 0 through 365
Week -- --
W ISO-8601 week number of year, weeks starting on Monday Example: 42 (the 42nd week in the year)
Month -- --
F A full textual representation of a month, such as January or March January through December
m Numeric representation of a month, with leading zeros 01 through 12
M A short textual representation of a month, three letters Jan through Dec
n Numeric representation of a month, without leading zeros 1 through 12
t Number of days in the given month 28 through 31
Year -- --
L Whether it's a leap year 1 if it is a leap year, 0 otherwise.
o ISO-8601 week-numbering year. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. Examples: 1999 or 2003
Y A full numeric representation of a year, 4 digits Examples: 1999 or 2003
y A two digit representation of a year Examples: 99 or 03
Time -- --
a Lowercase Ante meridiem and Post meridiem am or pm
A Uppercase Ante meridiem and Post meridiem AM or PM
B Swatch Internet time 000 through 999
g 12-hour format of an hour without leading zeros 1 through 12
G 24-hour format of an hour without leading zeros 0 through 23
h 12-hour format of an hour with leading zeros 01 through 12
H 24-hour format of an hour with leading zeros 00 through 23
i Minutes with leading zeros 00 to 59
s Seconds, with leading zeros 00 through 59
v Milliseconds. Example: 654
Timezone -- --
Z Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. -43200 through 50400
Full Date/Time -- --
c ISO 8601 date 2017-08-13T16:31:52.990Z
U Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) 1502642050

Unrecognized characters as well as characters immediately preceded by a \ in the format string will be printed as-is.

Unsupported PHP shorthand characters are: u, e, i, O, P, T, and r.

function parse(dateStr, formatStr){
if(!validate(dateStr, formatStr)) return false;
var year = new Date().getFullYear(),
month = 0, day = 1, hours = 0,
minutes = 0, seconds = 0, milliseconds = 0,
am=true, hr24=false;
for(var i=0; i<formatStr.length; i++){
switch(formatStr[i]){
case "\\": dateStr = dateStr.substr(2); i++; break;
case "Y": year = dateStr.substr(0,4); dateStr = dateStr.substr(4); break;
case "y":
var cy = (""+new Date().getFullYear()).substr(2);
var y = dateStr.substr(0,2);
year = (y>cy?"19":"20")+y;
dateStr = dateStr.substr(2);
break;
case "m":
month = dateStr.substr(0,2)-1;
dateStr = dateStr.substr(2);
break;
case "n":
var m = dateStr.match(/^(\d){1,2}/)[0];
month = m-1;
dateStr = dateStr.substr(m.length);
break;
case "d":
day = +dateStr.substr(0,2);
dateStr = dateStr.substr(2);
break;
case "j":
var m = dateStr.match(/^(\d){1,2}/)[0];
day = +m;
dateStr = dateStr.substr(m.length);
break;
case "g":
var h = dateStr.match(/^(\d){1,2}/)[0];
hours = h == 12 ? 0 : +h;
dateStr = dateStr.substr(h.length);
break;
case "G":
hr24 = true;
var h = dateStr.match(/^(\d){1,2}/)[0];
hours = +h;
dateStr = dateStr.substr(h.length);
break;
case "h":
var h = dateStr.substr(0,2);
hours = h == 12 ? 0 : +h;
dateStr = dateStr.substr(2);
break;
case "H":
hr24 = true;
hours = +dateStr.substr(0,2);
dateStr = dateStr.substr(2);
break;
case "i":
minutes = +dateStr.substr(0,2);
dateStr = dateStr.substr(2);
break;
case "s":
seconds = +dateStr.substr(0,2);
dateStr = dateStr.substr(2);
break;
case "v":
milliseconds = +dateStr.substr(0,3);
dateStr = dateStr.substr(3);
break;
case "a":
case "A":
if("pm" == dateStr.substr(0,2).toLowerCase()) am=false;
break;
default: dateStr = dateStr.substr(1); break;
}
}
if(!am && !hr24) hours+=12;
return new Date(year, month, day, hours, minutes, seconds, milliseconds);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="validate.js"></script>
<script src="parser.js"></script>
<script>
var date = parse("12/5/99 4:30:24.090 pm", "m/j/y g:i:s.v a");
console.log(date);
console.log(date.toString());
</script>
</body>
</html>
function validate(dateStr, formatStr){
const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
for(var i=0; i<formatStr.length; i++){
switch(formatStr[i]){
case "\\":
if(!/^\\/.test(dateStr) || formatStr[++i] !== dateStr[1]) return false;
dateStr = dateStr.substr(2);
break;
case "Y":
if(!/^(\d){4}/.test(dateStr)) return false;
dateStr = dateStr.substr(4);
break;
case "y":
if(!/^(\d){2}/.test(dateStr)) return false;
dateStr = dateStr.substr(2);
break;
case "m":
case "h":
if(!/^(\d){2}/.test(dateStr) || +dateStr.substr(0,2)>12 || !+dateStr.substr(0,2)) return false;
dateStr = dateStr.substr(2);
break;
case "n":
case "g":
var m = dateStr.match(/^(\d){1,2}/)||[];
if(!m.length || +m[0]>12 || !+m[0] || m[0].length>1&&+m[0]<10) return false;
dateStr = dateStr.substr(m[0].length);
break;
case "d":
if(!/^(\d){2}/.test(dateStr) || +dateStr.substr(0,2)>31 || !+dateStr.substr(0,2)) return false;
dateStr = dateStr.substr(2);
break;
case "j":
var m = dateStr.match(/^(\d){1,2}/)||[];
if(!m.length || +m[0]>31 || !+m[0] || m[0].length>1&&+m[0]<10) return false;
dateStr = dateStr.substr(m[0].length);
break;
case "G":
var m = dateStr.match(/^(\d){1,2}/)||[];
if(!m.length || +m[0]>23 || m[0].length>1&&+m[0]<10) return false;
dateStr = dateStr.substr(m[0].length);
break;
case "H":
if(!/^(\d){2}/.test(dateStr) || +dateStr.substr(0,2)>23) return false;
dateStr = dateStr.substr(2);
break;
case "i":
case "s":
if(!/^(\d){2}/.test(dateStr) || +dateStr.substr(0,2)>59) return false;
dateStr = dateStr.substr(2);
break;
case "v":
if(!/^(\d){3}/.test(dateStr)) return false;
dateStr = dateStr.substr(3);
break;
case "a":
case "A":
var m = dateStr.substr(0,2).toLowerCase();
if(!~['am','pm'].indexOf(m)) return false;
dateStr = dateStr.substr(2);
break;
default:
if(formatStr[i] !== dateStr[0]) return false;
dateStr = dateStr.substr(1);
break;
}
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment