Javascript and working with dates

R

rhaazy

I need to write some javascript that will return a date string in the
form mm/dd/yyyy.

The date needs to be today's date - 30 days.

Is there a relatively straight forward way to do this?

So far all I can find is a mess of variables for month, day, and year,
and combining some date functions together, etc etc. Seems like a lot
of work for what should be very simple.
 
S

SAM

rhaazy a écrit :
I need to write some javascript that will return a date string in the
form mm/dd/yyyy.

The date needs to be today's date - 30 days.

Is there a relatively straight forward way to do this?
http://www.merlyn.demon.co.uk/js-date1.htm#incr

So far all I can find is a mess of variables for month, day, and year,
and combining some date functions together, etc etc. Seems like a lot
of work for what should be very simple.


and what do you think we have to do when we want the date in french ?
dd/mm/yyyy

var D = new Date();
D.setMonth(D.getMonth()-1)
alert( D.getDate()+'/'+(+D.getMonth()+1)+'/'+D.getFullYear() );

--> 19/8/2008
 
R

rhaazy

rhaazy a écrit :




and what do you think we have to do when we want the date in french ?
  dd/mm/yyyy

var D = new Date();
D.setMonth(D.getMonth()-1)
alert( D.getDate()+'/'+(+D.getMonth()+1)+'/'+D.getFullYear() );

  --> 19/8/2008

Thats fine if all I want is a date, but to be able to subtract 30 days
from any given date introduces a huge mess of logic that needs to be
coded.
I decided to just find an open source date library that had decent
parsing functions for my purpose.

Thanks for the post.
 
J

Joost Diepenmaat

rhaazy said:
On Sep 19, 3:04 pm, SAM <[email protected]>
wrote:
Thats fine if all I want is a date, but to be able to subtract 30 days
from any given date introduces a huge mess of logic that needs to be
coded.

That's because dates - and times - are VERY messy. A library able to
manipulate dates that is complete enough to be /globally/ useful would
be very large. See for example the amount of stuff in the perl DateTime
project:

http://datetime.perl.org/?Modules
I decided to just find an open source date library that had decent
parsing functions for my purpose.

If you can find a decent library, that's probably the best way to handle
this problem.
 
S

Stevo

rhaazy said:
Thats fine if all I want is a date, but to be able to subtract 30 days
from any given date introduces a huge mess of logic that needs to be
coded.

I can't recall any language that makes dealing with dates easy.
 
L

Lasse Reichstein Nielsen

rhaazy said:
I need to write some javascript that will return a date string in the
form mm/dd/yyyy.

The date needs to be today's date - 30 days.

Is there a relatively straight forward way to do this?

var date = new Date();
date.setDate(date.getDate()-30);
var day = date.getDate();
var mth = date.getMonth();
var yr = date.getFullYear();
var format = (day < 10 ? "0" : "") + day + "/" +
(mth < 10 ? "0" : "") + mth + "/" +
yr;
So far all I can find is a mess of variables for month, day, and year,
and combining some date functions together, etc etc. Seems like a lot
of work for what should be very simple.

There isn't a date formatter built in. For most cases, it's not worth
it anyway. Just make one function to format your dates as you want
it and use that wherever it's needed.

/L
 
S

SAM

rhaazy a écrit :
Thats fine if all I want is a date,

don't you want date ? ("mm/dd/yyyy" you did say)
but to be able to subtract 30 days

and *absoloutly* 30 days ?
from any given date introduces a huge mess of logic that needs to be
coded.

Example with a trap over February:
==================================
var y = 2005, m = 03, d = 30; // 30/03/2005 (in dd/mm/yyyy)
var D = new Date(y, +m-1, d); // the orginal JS date
D.setDate(D.getDate()-30); // 30 days less
// that is done
alert( d+'/'+m+'/'+y+
' = original date\n'+
D.getDate()+'/'+(+D.getMonth()+1)+'/'+D.getFullYear()+
' = date - 30 days'):
 
S

SAM

Lasse Reichstein Nielsen a écrit :
var date = new Date();
date.setDate(date.getDate()-30);
var day = date.getDate();
var mth = date.getMonth();

months begin by '0' in JS. No ?
so :
var mth = +date.getMonth()+1;
 
S

sasuke

Usage:
    var d = new Date(2008, 3, 4);
    var dstr1 = d.fmt("%m/%d/%Y");
    var dstr2 = d.fmt("%d.%m.%Y");

/* a simple date formatting method */
Date.prototype.fmt = function (format) {
    var buffer = "";
    var chr, nxt;
    for (var i = 0, len = format.length; i < len; ++i) {
        chr = format.substr(i, 1);
        if (chr != "%") {
            buffer += chr;
            continue;
        }
        nxt = format.substr(i + 1, 1);
        if (nxt == "C") {           // 2-digit century (eg "19" or "20")
            buffer += String(Math.floor(   /* this shouldbe one line */
                this.getFullYear() / 100)).padFront("0", 2);
        } else if (nxt == "d") {    // day of month (01 to 31)
            buffer += String(this.getDate()).padFront("0", 2);
        } else if (nxt == "F") {    // month of year (1 to 12)
            buffer += (this.getMonth() + 1);
        } else if (nxt == "f") {    // day of month (1 to31)
            buffer += this.getDate();
        } else if (nxt == "H") {    // 24h hours (00 - 23)
            buffer += String(this.getHours()).padFront("0",2);
        } else if (nxt == "M") {    // minutes (00 - 59)
            buffer += String(this.getMinutes()).padFront("0", 2);
        } else if (nxt == "m") {    // month of year (01 to 12)
            buffer += String(this.getMonth() + 1).padFront("0", 2);
        } else if (nxt == "n") {    // newline
            buffer += "\n";
        } else if (nxt == "R") {    // 24h time (%H:%M)
            buffer += String(this.getHours()).padFront("0",2)
                    + ":"
                    + String(this.getMinutes()).padFront("0", 2);
        } else if (nxt == "S") {    // seconds (00 - 59)
            buffer += String(this.getSeconds()).padFront("0", 2);
        } else if (nxt == "T") {    // 24h time (%H:%M:%S)
            buffer += String(this.getHours()).padFront("0",2)
                    + ":"
                    + String(this.getMinutes()).padFront("0", 2)
                    + ":"
                    + String(this.getSeconds()).padFront("0", 2);
        } else if (nxt == "Y") {    // 4-digit year
            buffer += this.getFullYear();
        } else if (nxt == "y") {    // 2-digit year
            var y = String(this.getFullYear());
            buffer += y.substr(y.length -2, 2);
        } else if (nxt == "%") {    // literal "%" character
            buffer += "%";
        } else {
            buffer += format.substr(i, 2);
        }
        ++i; // skip next
    }
    return buffer;

}

In this form, it also requires an extension to the String prototype object:

/* left-pads the string with {chr} until it is {len} characters long */
String.prototype.padFront = function (chr, len) {
    if (this.length >= len) {
        return this;
    } else {
        return chr.repeat(len - this.length) + this;
    }

}

/* returns the string repeated {n} times */
String.prototype.repeat = function (n) {
    if (n < 1) return "";
    return (new Array(n + 1)).join(this);

}

Nice and compact implementation, 5 stars! A improvement here might be
using Array as buffer instead of String since Strings in Javascript
are immutable thereby preventing temporary string object creation.

/sasuke
 
T

Thomas 'PointedEars' Lahn

sasuke said:
Usage:
var d = new Date(2008, 3, 4);
var dstr1 = d.fmt("%m/%d/%Y");
var dstr2 = d.fmt("%d.%m.%Y");

/* a simple date formatting method */
Date.prototype.fmt = function (format) {
[50 lines of code]
}

In this form, it also requires an extension to the String prototype object:

/* left-pads the string with {chr} until it is {len} characters long */
String.prototype.padFront = function (chr, len) {
if (this.length >= len) {
return this;
} else {
return chr.repeat(len - this.length) + this;
}

}

/* returns the string repeated {n} times */
String.prototype.repeat = function (n) {
if (n < 1) return "";
return (new Array(n + 1)).join(this);

}

Nice and compact implementation, 5 stars!

Compact? Maybe String.prototype.padFront() and String.prototype.repeat().
A improvement here might be using Array as buffer instead of String

Or no user-defined buffer at all.
since Strings in Javascript are immutable thereby preventing temporary
string object creation.

Non sequitur.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Conrad said:
Here's one simple way to retro-fit a date formatting method. It
implements a subset of formats from strftime(3); the PHP function of the
same name is also similar. Some of the formats are missing, like the
names of months, week days, etc, because they were not required when the
method was written. Note: some of the formats are different from what
you might expect - read the comments and adjust the code as you see fit.

[x] done
Usage:
var d = new Date(2008, 3, 4);
var dstr1 = d.fmt("%m/%d/%Y");
var dstr2 = d.fmt("%d.%m.%Y");


/* a simple date formatting method */
Date.prototype.fmt = function (format) {
var buffer = "";
var chr, nxt;
for (var i = 0, len = format.length; i < len; ++i) {
chr = format.substr(i, 1);
if (chr != "%") {
buffer += chr;
continue;
}
nxt = format.substr(i + 1, 1);
if (nxt == "C") { // 2-digit century (eg "19" or "20")
buffer += String(Math.floor( /* this should be one line */
this.getFullYear() / 100)).padFront("0", 2);
} else if (nxt == "d") { // day of month (01 to 31)
buffer += String(this.getDate()).padFront("0", 2);
} else if (nxt == "F") { // month of year (1 to 12)
buffer += (this.getMonth() + 1);
} else if (nxt == "f") { // day of month (1 to 31)
buffer += this.getDate();
} else if (nxt == "H") { // 24h hours (00 - 23)
buffer += String(this.getHours()).padFront("0", 2);
} else if (nxt == "M") { // minutes (00 - 59)
buffer += String(this.getMinutes()).padFront("0", 2);
} else if (nxt == "m") { // month of year (01 to 12)
buffer += String(this.getMonth() + 1).padFront("0", 2);
} else if (nxt == "n") { // newline
buffer += "\n";
} else if (nxt == "R") { // 24h time (%H:%M)
buffer += String(this.getHours()).padFront("0", 2)
+ ":"
+ String(this.getMinutes()).padFront("0", 2);
} else if (nxt == "S") { // seconds (00 - 59)
buffer += String(this.getSeconds()).padFront("0", 2);
} else if (nxt == "T") { // 24h time (%H:%M:%S)
buffer += String(this.getHours()).padFront("0", 2)
+ ":"
+ String(this.getMinutes()).padFront("0", 2)
+ ":"
+ String(this.getSeconds()).padFront("0", 2);
} else if (nxt == "Y") { // 4-digit year
buffer += this.getFullYear();
} else if (nxt == "y") { // 2-digit year
var y = String(this.getFullYear());
buffer += y.substr(y.length -2, 2);
} else if (nxt == "%") { // literal "%" character
buffer += "%";
} else {
buffer += format.substr(i, 2);
}
++i; // skip next
}
return buffer;
}

Date.prototype.fmt = function(format) {
var d = this;
return format.replace(/%([CdFfHMmnRSTYy%])/g,
function(m, p1) {
switch (p1)
{
case "C": return String(Math.floor(d.getFullYear() / 100))
.padFront("0", 2);
case "d": return String(d.getDate()).padFront("0", 2);
case "F": return d.getMonth() + 1;
case "f": return d.getDate();
case "H": return String(d.getHours()).padFront("0", 2);
case "M": return String(d.getMinutes()).padFront("0", 2);
case "m": return String(d.getMonth() + 1).padFront("0", 2);
case "n": return "\n";
case "R": return String(d.getHours()).padFront("0", 2)
+ ":"
+ String(d.getMinutes()).padFront("0", 2);
case "S": return String(d.getSeconds()).padFront("0", 2);
case "T": return String(d.getHours()).padFront("0", 2)
+ ":"
+ String(d.getMinutes()).padFront("0", 2)
+ ":"
+ String(d.getSeconds()).padFront("0", 2);
case "Y": return d.getFullYear();
case "y": return String(d.getFullYear() % 100).padFront("0", 2);
default: return p1;
}
});
};


PointedEars
 
D

Dr J R Stockton

I need to write some javascript that will return a date string in the
form mm/dd/yyyy.

Deprecanda est FFF.
The date needs to be today's date - 30 days.

Be aware that the user's date may differ from your date.
Is there a relatively straight forward way to do this?

D = new Date() ; D.setDate(D.getDate()-30)
with (D) X = String(101000000 + getMonth()*1e6 + getDate()*1e4 +
getFullYear())
.replace(/(.)(\d\d)(\d\d)/, "$2/$3/")
with (D) X = String(100 + getFullYear()*1e4 + getMonth()*1e2 +
getDate())
.replace(/(\d{4})(\d\d)(\d\d)/, "$2/$3/$1")

Only one of the with statements is required. This gives 2 2 4 digit
fields, unlike some.
 
S

sasuke

Date.prototype.fmt = function(format) {
  var d = this;
  return format.replace(/%([CdFfHMmnRSTYy%])/g,
    function(m, p1) {
      switch (p1)
      {
        case "C": return String(Math.floor(d.getFullYear() / 100))
                         .padFront("0", 2);
        case "d": return String(d.getDate()).padFront("0", 2);
        case "F": return d.getMonth() + 1;
        case "f": return d.getDate();
        case "H": return String(d.getHours()).padFront("0", 2);
        case "M": return String(d.getMinutes()).padFront("0", 2);
        case "m": return String(d.getMonth() + 1).padFront("0", 2);
        case "n": return "\n";
        case "R": return String(d.getHours()).padFront("0", 2)
                         + ":"
                         + String(d.getMinutes()).padFront("0", 2);
        case "S": return String(d.getSeconds()).padFront("0", 2);
        case "T": return String(d.getHours()).padFront("0", 2)
                         + ":"
                         + String(d.getMinutes()).padFront("0", 2)
                         + ":"
                         + String(d.getSeconds()).padFront("0", 2);
        case "Y": return d.getFullYear();
        case "y": return String(d.getFullYear() % 100).padFront("0", 2);
        default: return p1;
      }
    });
};

Very good modifications. But won't it be better if we use a cached
copy of the RegExp native object instead of creating a new one on each
invocation?

That would be implementation dependant. After a quick check it looks
like an array buffer is actually a little slower in the browsers that
I've tested. IIRC, the speed difference between string concatenation and
array joins only favors the array if the substrings are rather long.

I necessarily didn't mean performance in terms of speed, but more so
in terms of memory. Though there is no reliable way of tracking memory
allocation in browser embedded Javascript, I am pretty sure the Array
method ends up taking much less memory than the String concatenation
approach.

/sasuke
 
G

Guest

I need to write some javascript that will return a date string in the
form mm/dd/yyyy.

The date needs to be today's date - 30 days.

Is there a relatively straight forward way to do this?

Yes!

Let JS do all the complex logic of various month lengths, leap years and
year boundaries.

var past = new Date(new Date().getTime() - 30*24*60*60000)
var mm=past.getMonth().valueOf()+1
if (mm<10) mm="0"+mm
var dd=past.getDate()
if(dd<10) dd="0"+dd
result=mm+"/"+dd+"/"+past.getFullYear()

I'm sure that there is a cleaner way to force two digit fields.

If m/d/yyyy is acceptable then:
var past = new Date(new Date().getTime() - 30*24*60*60000)
result=(past.getMonth().valueOf()+1)+"/"+dd=past.getDate()+"/"+past.getFullYear()

Can't get much simplier than two lines.

K.
 
G

Guest

Yes!

Let JS do all the complex logic of various month lengths, leap years and
year boundaries.

var past = new Date(new Date().getTime() - 30*24*60*60000)
var mm=past.getMonth().valueOf()+1
if (mm<10) mm="0"+mm
var dd=past.getDate()
if(dd<10) dd="0"+dd
result=mm+"/"+dd+"/"+past.getFullYear()

I'm sure that there is a cleaner way to force two digit fields.

If m/d/yyyy is acceptable then:
var past = new Date(new Date().getTime() - 30*24*60*60000)
result=(past.getMonth().valueOf()+1)+"/"+dd=past.getDate()+"/"+past.getFullYear()

Oppps - typo above
result=(past.getMonth().valueOf()+1)+"/"+past.getDate()+"/"+past.getFullYear()
 
L

Lasse Reichstein Nielsen

Let JS do all the complex logic of various month lengths, leap years and
year boundaries.

Agree ...
var past = new Date(new Date().getTime() - 30*24*60*60000)

which is why this is not the way to do it. You are asking for a point
in time that is 30 * 24 hours earlier. That's not always the same as
30 days. Some days are 25 hours, some are 23, due to daylight saving
transition. This code will fail to give the correct day in some cases.

Use:
var past = new Date();
past.setDate(past.getDate()-30);
That gives the same time, 30 days earlier. Let Javascript do the
calculation for you.

/L
 
G

Guest

Agree ...


which is why this is not the way to do it. You are asking for a point
in time that is 30 * 24 hours earlier. That's not always the same as
30 days. Some days are 25 hours, some are 23, due to daylight saving
transition. This code will fail to give the correct day in some cases.
An interesting point. This error will occur if and only if one includes a
23 or 25 hour day AND is in a boundry period of the first or last hour of
the day. That can happen only two hours a year.

One can correct for this by shifting the current time to noon:
var past = new Date( new Date().setHours(12) - 30*24*60*60000 )

The OP did not indicate if the question was 30 24hour days or 30 calendar
days.

Use:
var past = new Date();
past.setDate(past.getDate()-30);
That gives the same time, 30 days earlier.

NO!

That will work only if the previous month is 30 days (some are 28, 29, 31).
So it is correct only in three months - June, October and December. It
fails in most of May because in the USA DST happens in April.

BTW, if you start in January, then you will go forward some 11 months
unless you adjust the year also but even then the December day of month
will be one low.
 
R

rhaazy

please ignore this post -- shifting the date does work

sorry

Thank you everyone for the discussion. This code is a lot cleaner
than what I had, and I learned a lot about the various date functions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top