0

I'm using the https://fullcalendar.io/ calendar plugin in an app. I provide the calendar with data with the dates in iso8601 format, like this, "2021-09-15T14:30:00+01:00", and the calendar does a good job of showing those times adjusted for the timezone set in the browser.

Eg, if the browser is in a "+01:00" timezone then that time shows up as 14:30, but if it's in a "+02:00" timezone it shows up as 15:30, etc.

My problem is that I'd like to show those times in other contexts, outside of the calendar, and I don't want to output different things from the server - I want the conversion to happen in the browser, using javascript.

It occurred to me that I could do something like this: output the time in a span with the iso861 string in a data attribute, perhaps with a class as well which acts as a trigger for some general js on the page. But, is there a simple way in JS to convert the iso8601 time string to a time using the browser's timezone setting? I suppose I would need to have another data attribute that has some info on how I want it to be formatted, something like "%H:%M" in this case (if I want to output "14:30" or "15:30").

Note - we use jquery and i will use that in my example JS below.

Something like this:

<!-- in html - the span contains the default unconverted time -->

<span class="convertable-time" data-iso8601="2021-09-15T14:30:00+01:00" data-datetime-format="%H:%M">14:30</span>

and then in the JS something like this (this is using jquery but the solution doesn't need to)

$(".convertable-time").each(function(i,el){
  el = $(el);
  el.html(convertIso8601StringToLocalTime(el.data("iso8601"), el.data("datetime-format"));
});

function convertIso8601StringToLocalTime(string, format){
  //eg string = "2021-09-15T14:30:00+01:00"
  //eg format = "%H:%M"
  // ??
}

What would I put in the convertIso8601StringToLocalTime function? Note - i'm not wedded to the exact format string of "%H:%M", if there is a more standard way of specifying a datetime format in JS then i'm happy to use it. thanks.

6

1 Answer 1

1

This is what I ended up doing:

//expects timestring to be an iso8601 formatted datetime string eg "2021-09-15T14:30:00+01:00"
//accepted strings for "format": copied from ruby's DateTime#strftime method
// %M - minutes
// %H - hours
// %S - seconds
// %d - day of the month
// %Y - year four digits
// %y - year two digits
// %m - month (as a number)
function convertIso8601StringToLocalTime(timestring, format){
  //set default format
  if((typeof(format) == "undefined") || (format == "")){
    format = "%H:%M";
  }
  var date = new Date(timestring);
  var replacements = {
    "getMinutes": /\%M/g,
    "getHours": /\%H/g,
    "getDate": /\%d/g,
    "getFullYear": /\%Y/g,
    "getMonth": /\%m/g
  }
  for (const [function_name, regex] of Object.entries(replacements)) {
    if(format.match(regex)){
      format = format.replace(regex, date[function_name]());
    }
  }
  // year two digits doesn't have a method we can call on a Date as far as I can see
  // ('getYear()' returns '121' for me which is mysterious)
  // so we do it 'manually' here by modding the full year by 100
  if(format.match(/\%y/g)){
    format = format.replace(/\%y/g, (date.getFullYear() % 100));
  }
  return format;
}
Sign up to request clarification or add additional context in comments.

2 Comments

So you just wanted a simple formatter? There's one here that uses PHP tokens, I think it should be fairly simple to convert to other token schemes. ECMAScript allows default parameters, so instead of if (typeof format == 'undefined'...) etc. you can do function convertIso8601StringToLocalTime(timestring, format = '%H:%M'){...}. :-)
Thanks - the reason I didn't put the default parameter in was that i thought that format might come through as an empty string sometimes, and wanted to pick that up as being equivalent to the "undefined" case, which the default param wouldn't do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.