1

I need to convert an ISO-8601 duration into a date using JavaScript or Java. For example ISO-8601 like P0000-00-60T00:00:00 and current date like 2014-11-30 means, i want to get output like 2015-01-29

Satheesh Natarajan
  • 459
  • 2
  • 7
  • 31
  • What do you mean by date? a `java.util.Date` or what? – meskobalazs Dec 03 '14 at 11:07
  • What does that `60` mean? – Basil Bourque Dec 03 '14 at 11:17
  • @BasilBourque @meskobalazs i want to convert a duration. but your answer is used for converting the date. 'P0000-00-60T00:00:00` here P represents `Period` – Satheesh Natarajan Dec 03 '14 at 11:25
  • You are not showing an [ISO 8601 Duration](http://en.m.wikipedia.org/wiki/ISO_8601#Durations). You are showing a date-time value with two anomalies: a `P` in front and a mysterious `60` in the middle. – Basil Bourque Dec 03 '14 at 11:31
  • Another duplicate: http://stackoverflow.com/q/14934089/642706 – Basil Bourque Dec 03 '14 at 11:37
  • Another duplicate: http://stackoverflow.com/q/15977637/642706 – Basil Bourque Dec 03 '14 at 11:42
  • @BasilBourque That your comment link format of the ISO-8601 duration was different, but my format conversion is different. please check this link http://en.wikipedia.org/wiki/ISO_8601#Durations – Satheesh Natarajan Dec 03 '14 at 11:42
  • Your last comment is not understandable. Your own link shows the the standard format for an ISO 8601 duration is `PnYnMnDTnHnMn`, *not* the string shown in your Question. I suggest you search StackOverflow as this topic has been covered many times already. – Basil Bourque Dec 03 '14 at 11:47
  • 1
    @check the last paragraph of the duration in that link. They provide alternative format for ISO-8601 duration. They mention the format like this `P[YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]' and example like this 'P0003-06-04T12:30:05' – Satheesh Natarajan Dec 03 '14 at 11:53
  • @BasilBourque check the below answer which provide by 'RobG'. it's working fine. please don't devote my question. The question was correct. – Satheesh Natarajan Dec 03 '14 at 12:25
  • @meskobalazs check the below answer which provide by 'RobG'. it's working fine. please don't devote my question. The question was correct – Satheesh Natarajan Dec 03 '14 at 12:27
  • @SatheeshSanthosh [A] I stand corrected. I did not realize you were using the alternate form of the ISO 8601 Duration. I retracted my Vote To Close as this alternate format does not seem to have duplicate questions. [B] Note that your use of `60` is incorrect, as that alternate format forbids exceeding the moduli, so sixty days is not allowed. If you want sixty days you must use the main format, `P60D`. – Basil Bourque Dec 03 '14 at 12:35
  • 1
    I haven't downvoted it. However, next time you should decide if it is a Java or a JavaScript question. – meskobalazs Dec 03 '14 at 12:35
  • For Java, look at the [Joda-Time](http://www.joda.org/joda-time/) library. It can handle both parsing and generating ISO 8601 Durations in the main format. I do not know if it handles the alternate format. – Basil Bourque Dec 03 '14 at 12:40

1 Answers1

2

In ECMAScript, parsing an ISO 8601 date like "2014-11-30" is straight forward. A function to do that should also validate the date and return NaN if it's invalid:

function parseYMD(s) {
  var b = s.split(/\D/);
  var d = new Date(b[0], --b[1], b[2]);
  return d && d.getFullYear() == b[0] && d.getDate() == b[2]? d : NaN;
}

You can apply similar logic to parse a period and add it to the date:

// Period in extended format: Py-m-dTh:m:s
// Modifies the date passed in and returns it
function addPeriod(p, d) {
  d = d || new Date();
  var b = p.match(/\d+/g);

  d.setFullYear(d.getFullYear() + +(b[0]), d.getMonth() + +(b[1]), d.getDate() + +(b[2]));
  d.setHours(d.getHours() + +(b[3]), d.getMinutes() + +(b[4]), d.getMinutes() + +(b[5]))
  return d;
}

The above should also validate that the parts of the period don't exceed their moduli, e.g. months can't be more than 12, hours more than 24, minutes more than 59, etc.

// Parse string to date
var date = parseYMD('2014-11-21');
console.log(date);

// Add a period to a date
addPeriod('P1-0-0T10:10:10', date);
console.log(date);
RobG
  • 142,382
  • 31
  • 172
  • 209