...

View Full Version : Formatting dates for display



AndrewGSW
09-17-2012, 07:39 PM
While I'm on a roll ;) someone may also be interested in formatting dates for display - using format codes such as 'dd mmm yyyy'.


<!DOCTYPE html>
<html>
<head>
<title>Formatting Dates</title>

<script type="text/javascript">
var monthNames = ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"];
var dayNames = [ "Sunday", "Monday", "Tueday", "Wednesday", "Thursday",
"Friday", "Saturday" ];
var shortMths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"];
var shortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

function formatDate(sFormat, aDate) {
// Example use: FormatDate('ddd, dd mmm YYYY hh:nn'); - use 'nn' for mins
// If aDate is not supplied the current date is assumed.
var currDT = aDate || new Date();

sFormat = sFormat.toUpperCase();
function replaceDTChars(match) {
switch (match) {
case 'D': return currDT.getDate();
case 'DD':
var currDate = currDT.getDate();
return ( currDate < 10 ? "0" : "" ) + currDate;
case 'DDD': return dayNames[currDT.getDay()].substring(0,3);
case 'DDDD': return dayNames[currDT.getDay()];
case 'M': return currDT.getMonth()+1;
case 'MM':
var currMonth = currDT.getMonth()+1;
return ( currMonth < 10 ? "0" : "" ) + currMonth;
case 'MMM': return monthNames[currDT.getMonth()].substring(0,3);
case 'MMMM': return monthNames[currDT.getMonth()];
case 'Y':
case 'YY': return ('' + currDT.getFullYear()).substring(2);
case 'YYY':
case 'YYYY': return '' + currDT.getFullYear();
case 'H': return currDT.getHours();
case 'HH':
var currHr = currDT.getHours();
return ( currHr < 10 ? "0" : "" ) + currHr;
case 'N': return currDT.getMinutes();
case 'NN':
var currMin = currDT.getMinutes();
return ( currMin < 10 ? "0" : "" ) + currMin;
case 'S': return currDT.getSeconds();
case 'SS':
var currSecs = currDT.getSeconds();
return ( currSecs < 10 ? "0" : "" ) + currSecs;
default: return match;
}
}
return sFormat.replace(/D{1,4}|M{1,4}|Y{1,4}|H{1,2}|N{1,2}|S{1,2}/g,
function(m){return replaceDTChars(m)});
}

function formatIt() {
var thedate = document.getElementById('thedate');
var asdate = new Date(thedate.value);
var theformat = document.getElementById('theformat').value;
document.getElementById('theresult').innerHTML = formatDate(theformat, asdate);
}
</script>

</head>

<body>
<h1>Formatting Dates</h1>

<label>Enter a Date in the standard format YYYY/MMM/DD HH:MM:
<input type="text" id="thedate" name="thedate" value="">
</label><br>
<label>Enter the required format e.g. 'dd/mmm/yy':
<input type="text" id="theformat" name="theformat" value="dd/mmm/yyyy">
</label>
<button onclick="formatIt()">Format</button>
<p id="theresult">Result will appear here..</p>
</body>
</html>

It doesn't handle 12 hour clocks (am/pm) but I could leave this as an exercise for you :D.

AndrewGSW
09-22-2012, 01:11 AM
I may as well include the following, very similar, function that return's today's date as a formatted string. (It also requires the day/month arrays from the first post.)

function GetToday(sFormat) {
// Returns a string with today's date e.g. GetToday("d mmm yy hh:nn:ss").
// Defaults to YYYY/MM/DD.
var currDT = new Date(),
D = currDT.getDate(), DDDD = DayNames[currDT.getDay()],
DDD = DDDD.substr(0,3),
M = currDT.getMonth()+1, MMMM = MonthNames[currDT.getMonth()],
MMM = MMMM.substr(0,3),
YYYY = currDT.getFullYear(), YY = ('' + YYYY).substr(2,2),
H = currDT.getHours(), N = currDT.getMinutes(), S = currDT.getSeconds(),
// pad with leading zeros, if required
DD = ( D < 10 ? "0" : "" ) + D,
MM = ( M < 10 ? "0" : "" ) + M, HH = ( H < 10 ? "0" : "" ) + H,
NN = ( N < 10 ? "0" : "" ) + N, SS = ( S < 10 ? "0" : "" ) + S;

sFormat = ( sFormat ) ? sFormat.toUpperCase() : 'YYYY/MM/DD';
var sParsed = sFormat.replace(/D{1,4}|M{1,4}|Y{2,4}|H{1,2}|N{1,2}|S{1,2}/g,
function (m) {
try {
return eval(m);
} catch (e) {
return '';
}
});
return sParsed;
}
It does use eval :o unfortunately, but this is very useful for this particular function.

AndrewGSW
09-26-2012, 10:04 PM
I've modified getToday() so that it can be used to return a formatted version of any supplied date, or today if omitted. Again, it requires the arrays DayNames and MonthNames from my first post.


var FormattedDate = function (sFormat, dDate) {
// Returns: A string version of the date-value dDate,
// or of today's date if dDate is omitted.
// Usage: FormattedDate("d mmm yy hh:nn:ss") or
// FormattedDate("dddd dd mmmm", date_var)
// Defaults to YYYY/MM/DD.
var dDate = dDate || new Date(),
D = dDate.getDate(), DDDD = DayNames[dDate.getDay()],
DDD = DDDD.substr(0,3),
M = dDate.getMonth()+1, MMMM = MonthNames[dDate.getMonth()],
MMM = MMMM.substr(0,3),
YYYY = dDate.getFullYear(), YY = ('' + YYYY).substr(2, 2),
H = dDate.getHours(), N = dDate.getMinutes(), S = dDate.getSeconds(),
// pad with leading zeros, if required
DD = ( D < 10 ? "0" : "" ) + D,
MM = ( M < 10 ? "0" : "" ) + M, HH = ( H < 10 ? "0" : "" ) + H,
NN = ( N < 10 ? "0" : "" ) + N, SS = ( S < 10 ? "0" : "" ) + S;

sFormat = ( sFormat ) ? sFormat.toUpperCase() : 'YYYY/MM/DD';
var sParsed = sFormat.replace(/D{1,4}|M{1,4}|Y{2,4}|H{1,2}|N{1,2}|S{1,2}/g,
function (m) {
try {
return eval(m);
} catch (e) {
return '';
}
});
return sParsed;
};
And, again, I haven't incorporated AM/PM - although this is a possibility. PS I appreciate that this is really just an alternative (more compact) version of my first (formatDate) function.

Feedback welcome :)

AndrewGSW
09-30-2012, 02:23 PM
Prototype that allows for am/pm (or AM/PM) or just a 12-hour clock optional argument:

Date.prototype.format = function (sFormat, twelve) {
// Returns: A string version of the date.
// Usage: date_instance.format("d mmm yy hh:nn:ss ap") or
// date_instance.format("dddd dd mmmm hh:nn", true)
// Defaults to YYYY/MM/DD.
// twelve == true for a 12hr clock, or just AP or ap within
// sFormat (for AM/PM or am/pm).
var MonthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"];
var DayNames = [ "Sunday", "Monday", "Tueday", "Wednesday", "Thursday",
"Friday", "Saturday" ];
var dDate = this || new Date(),
D = dDate.getDate(), DDDD = DayNames[dDate.getDay()],
DDD = DDDD.substr(0,3),
M = dDate.getMonth()+1, MMMM = MonthNames[dDate.getMonth()],
MMM = MMMM.substr(0,3),
YYYY = dDate.getFullYear(), YY = ('' + YYYY).substr(2, 2),
H = dDate.getHours(), N = dDate.getMinutes(), S = dDate.getSeconds(),
ap = (H > 11) ? "pm" : "am",
// pad with leading zeros, if required
DD = ( D < 10 ? "0" : "" ) + D,
MM = ( M < 10 ? "0" : "" ) + M,
NN = ( N < 10 ? "0" : "" ) + N,
SS = ( S < 10 ? "0" : "" ) + S;
var AP = (sFormat && (sFormat.toUpperCase().indexOf('AP')+1)) ?
((sFormat.indexOf('ap')+1) ? ap : ap.toUpperCase()) : '';
if (twelve || AP) {
H = H % 12 || 12;
}
var HH = ( H < 10 ? "0" : "" ) + H;
sFormat = ( sFormat ) ? sFormat.toUpperCase() : 'YYYY/MM/DD';
return sFormat.replace(/D{1,4}|M{1,4}|Y{2,4}|H{1,2}|N{1,2}|S{1,2}|AP/g,
function (m) {
try {
return eval(m);
} catch (e) {
return '';
}
});
};

AndrewGSW
10-01-2012, 01:50 AM
For completeness the following version allows for milliseconds and suffixes (1st, 2nd, etc.).

Use z or zzz for milliseconds, as in: not quite Zero!
Use xx for suffixes, as in: suffiXX (plural)

I don't think timezones or offsets belong in this method; this information can be appended to the resultant string if required.

If you would like something placed within the string, I suggest calling the method twice and creating the string in this way. Similarly, if you want the day (MON) capitalized (but not the month) just use the method twice (or more) and use toUpperCase().


Date.prototype.format = function (sFormat, twelve) {
// Returns: A string version of the date.
// Usage: date_instance.format("d mmm yy hh:nn:ss ap") or
// date_instance.format("dddd dd mmmm hh:nn", true)
// Defaults to YYYY/MM/DD.
// twelve == true for a 12hr clock, or just AP or ap within
// sFormat (for AM/PM or am/pm).
// Use z or zzz for milliseconds and xx for suffixes (st, nd, etc.).
var MonthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"];
var DayNames = [ "Sunday", "Monday", "Tueday", "Wednesday", "Thursday",
"Friday", "Saturday" ];
var dDate = this || new Date(),
D = dDate.getDate(), DDDD = DayNames[dDate.getDay()],
DDD = DDDD.substr(0,3),
M = dDate.getMonth()+1, MMMM = MonthNames[dDate.getMonth()],
MMM = MMMM.substr(0,3),
YYYY = dDate.getFullYear(), YY = ('' + YYYY).substr(2, 2),
H = dDate.getHours(), N = dDate.getMinutes(), S = dDate.getSeconds(),
Z = dDate.getMilliseconds(),
ap = (H > 11) ? "pm" : "am",
// pad with leading zeros, if required
DD = ( D < 10 ? "0" : "" ) + D,
MM = ( M < 10 ? "0" : "" ) + M,
NN = ( N < 10 ? "0" : "" ) + N,
SS = ( S < 10 ? "0" : "" ) + S,
ZZZ = ( Z < 10 ? "00" : (Z < 100 ? "0" : "") ) + Z, XX;
var AP = (sFormat && (sFormat.toUpperCase().indexOf('AP')+1)) ?
((sFormat.indexOf('ap')+1) ? ap : ap.toUpperCase()) : '';
if (twelve || AP) {
H = (H < 12) ? (H || 12) : ((H - 12) || 12);
}
var HH = ( H < 10 ? "0" : "" ) + H;
XX = (D == 1 || D == 21 || D == 31) ? "st" :
((D == 2 || D == 22) ? "nd" : ((D == 3 || D == 23) ? "rd" : "th"));
sFormat = ( sFormat ) ? sFormat.toUpperCase() : 'YYYY/MM/DD';
var sParsed = sFormat.replace(/D{1,4}|M{1,4}|Y{2,4}|H{1,2}|N{1,2}|S{1,2}|Z{1,3}|XX|AP/g,
function (m) {
try {
return eval(m);
} catch (e) {
return '';
}
});
return sParsed;
};

felgall
10-01-2012, 11:33 PM
I wrote a Date.format method a few years ago that replicates the PHP format command as closely as it is possible to do in JavaScript so that you can use identical codes for how you want the date and time formatted in both places. There were only three of the codes in PHP that can't be implemented in JavaScript and I found five extras to implement that the PHP version didn't cater for - see http://www.felgall.com/datemethods.htm (which includes that and all the other extra methods I created to extend date processing).



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum