Format date with Elixir DateTime to RFC2616 format - datetime

I want to implement a piece of code that converts a datetime object like ~U[2022-06-07 18:37:16.842920Z] to a format like Tue, 7 Jun 2022 18:37:16 GMT. I do not want to use the Calendar.DateTime.Format.httpdate since our codebase already uses DateTime.
I need it to send in API headers with RFC2616 format. Any help is appreciated.

Elixir 1.11.0 introduced Calendar.strftime/3 that is what you need. Please note that DateTime and Calendar are different built-in modules that serve different purposes. There should be no problem in using them combined.
~U[2022-06-07 18:37:16.842920Z]
|> DateTime.shift_zone!("Etc/UTC")
|> Calendar.strftime("%a, %-d %b %Y %X GMT")
# => "Tue, 7 Jun 2022 18:37:16 GMT"

Related

ISO 8601 Datetime understanding

I am trying to understanding the date reading of ISO 8601 format and cant find a good doc to read.
If I am getting time in my code like this "2018-08-18T00:00:00+1000", is this local time or UTC time?
and when I convert it using Convert.ToDateTime("2018-08-18T00:00:00+1000"), I get the following date time {8/17/2018 7:00:00 AM}. I am not sure if that is UTC datetime or local?
What is the math behind "2018-08-18T00:00:00+1000" getting converted to {8/17/2018 7:00:00 AM}, I cant get my head around this.
You are asking for the math behind 2018-08-18T00:00:00+1000 being shown as 8/17/2018 7:00:00 AM.
First of all 8/17/2018 7:00:00 AM is just another format to display the date and time. Converted to an ISO 8601 string it would look like this: 2018-08-17T07:00:00.
+1000 at the end of the 2018-08-18T00:00:00+1000 representation is a timezone offset. You could read that string as August 18, 2018 in UTC plus ten hours. So it would be the same as 2018-08-18T10:00:00Z.
So we have a UTC date of August 18, 2018 10 AM, which is shown as a locale date of August 17, 2018 7 AM. That would mean that you are in a timezone which is 27 hours behind UTC.
A timezone behing more than 12 hours before (or 14 after) UTC does not exist (as far as I'm aware of). Therefore I assume that you have a typo in your example. Another reason could be a totally broken date parser.
But I still hope you got the math behind the conversion.

How to convert a String into an Ecto.DateTime in Elixir?

I need to convert a string containing a valid UTC time to an Ecto.DateTime one, which I will insert it into my database with the correct format later. I have tried using the Ecto.DateTime.cast(date) method but it doesn't seem to work. The string is Sat Aug 04 11:48:27 +0000 2012 and comes from the Twitter API.
I know there are libraries such as Timex which I didn't inspect yet. Is there any easy working solution already built in Elixir?
There's no built-in solution in Elixir or Erlang for parsing DateTime values of this format:
Sat Aug 04 11:48:27 +0000 2012
You can certainly write a parser yourself, but it's neither going to be short or simple. You'll have to split the string, get the values of both date and time parameters, convert month strings to month integers, parse the timezone, represent the complete value in Elixir/Erlang DateTime formats and then finally cast it to Ecto.DateTime. See the following links:
Elixir Tips - Date Parsing
Erlang - How Can I Parse RFC1123 Dates Into An Erlang Term?
Convert timestamp to datetime in erlang
Using Timex is the best option here.
It's a well written library that allows you to stay away from the chaos of inner workings of Date/Time. With Timex, you can parse your string like this:
"Sat Aug 04 11:48:27 +0000 2012"
|> Timex.parse!("%a %b %d %T %z %Y", :strftime)
|> Ecto.DateTime.cast!
# => #Ecto.DateTime<2012-08-04 11:48:27>
Note: Timex has built-in support for a lot of the common DateTime formats, and I found it weird that a DateTime format being sent by Twitter wasn't supported - so I wrote one for you. Maybe double check to see if your string is correct? Also take a look at Timex Parsing and Formatting documentation.

MomentJs and Timezone Abbreviations

I am having trouble with the momentjs library
the line
moment("Mon Oct 14 01:00:00 GMT 2013") parses correctly
but the line
moment("Mon Oct 14 01:00:00 BST 2013") throws an invalid date
I have tried building a format string but the zz format which is what I think I need is deprecated, is there a way to make it skip the BST/GMT bit completely as I am only interested in the date
Thanks in advance.
Time zone abbreviations aren't unique, so they cannot be parsed. You can ignore it by putting any non-format character as a placeholder:
moment("Mon Oct 14 01:00:00 BST 2013","ddd MMM DD HH:mm:ss ? YYYY")
But you should be aware that by ignoring it, you'll be assuming the local time zone of the computer where the code is running. Set your computer for another time zone and call .format() on this and you'll see what I mean.
Perhaps you don't care about time zones and just want to reformat this to something else. That's fine, but what if you provide a date that's invalid because of a daylight saving time transition in the computer's local time zone? Your browser will either skip backward or forward depending on which browser your running. To avoid that, you should work in UTC instead of in the local time. Even though your input value is from some other time zone entirely, working in UTC will ensure it doesn't get mangled.
moment.utc("Mon Oct 14 01:00:00 BST 2013","ddd MMM DD HH:mm:ss ? YYYY")

How to properly place Date in <pubdate> element on RSS feed

I'm using RSS Graffitty to post RSS items to a facebook page.
The app told me the items were missing the publication date so I added this tag:
echo "<pubdate>".$row['Date']."</pubdate>";
$row['Date'] is obtained from my MySQL database and it's a Datetime column.
How must I format it/echo it so it's recognized by the RSS feed? Must I change the element?
Thanks
RSS 2.0 specifications on the <pubDate> element should conform to the RFC 822 Date and Time syntax. Namely, to display it in the following format:
Fri, 21 Dec 2012 10:00:01 GMT
If you error run your RSS feed through the W3C Feed Validator you'll note these examples of valid RFC822 date-times:
<pubDate>Wed, 02 Oct 2002 08:00:00 EST</pubDate>
<pubDate>Wed, 02 Oct 2002 13:00:00 GMT</pubDate>
<pubDate>Wed, 02 Oct 2002 15:00:00 +0200</pubDate>
If you wanted to use MySQL formatting, you'd call the column with the following use of date_format(), adjusting the UTC modifier/marker as necessary:
date_format(Date, '%a, %d %b %Y %H:%i:%s')
Or you can do it via the PHP date method with DATE_RSS setting the format for you:
echo "<pubdate>".date(DATE_RSS, strtotime($row['Date']))."</pubdate>";
Make sure your <pubDate> element appear within its parent <item> node.
Also note that this element is case-sensitive. You must output pubDate with the capital D and not all lowercase (pubdate) as other elements can.
Just a hint: the -r switch in the php date function is the shorthand for the RFC 2822 format, which actually does yield a four digit year.
See PHP Doc for reference.

Javascript ASP.net date format without timezone info - timezone offsets

I have a client side JavaScript that generates a date in JavaScript( new Date(2007,5,1)).
I need this date passed through to a hidden field that the code behind can access.
My issue is that when the hidden field is converted into a DotNet datetime, the time is incorrect. This is because the JavaScript is including timezone info from the client browser.
DotNet is then using this info to recalculate the time based on the difference between the server time and the client time.
What i need from the JavaScript is just the year, month and day.
I don't want to pass through 3 int values to my code behind as this will be a major change to the whole app.
What is the best way for me to accomplish this?
If i can set a UTC time with no timezone info I think that might work.
Any help is appreciated.
demo
If I understood it correctly,
you need .toDateString()
var date = new Date(2007,5,1);
document.write(date);
document.write("<br><br>versus<br><br>");
document.write(date.toDateString());
prints
Fri Jun 01 2007 00:00:00 GMT+0800 (Taipei Standard Time)
versus
Fri Jun 01 2007
You can use DateTimeOffset.ParseExact to parse a string to a DateTimeOffset value using the format you specify:
string dateString = "Fri Jun 01 2007 00:00:00 GMT+08:00";
DateTimeOffset date = DateTimeOffset.ParseExact(dateString, "ddd MMM dd yyyy hh:mm:ss 'GMT'zzz", CultureInfo.InvariantCulture);
You have to put GMT in quotes otherwise M will be interpreted as a format character.
Unfortunatelly, it is not possible to ignore part of the string value. If your string includes the name of the timezone you have to split it first and get the part without the description
string dateString = "Fri Jun 01 2007 00:00:00 GMT+08:00 (Taipei Standard Time)";
var parts=dateString.Split('(');
string datePart = parts[0].TrimEnd();
var date=DateTimeOffset.ParseExact(datePart,"ddd MMM dd yyyy hh:mm:ss 'GMT'zzz",CultureInfo.InvariantCulture);
You can build up a string from the javascript Date object you have created - it has getDate(), getMonth() and getFullYear() methods that you can use to build up the exact string you want in the hidden field.
I would recommend to use a format specification in C# when you get the values in the code behind file. Let me explain what I mean -
The date time format for the Date(...) in JavaScript is as follows
"Tue Jun 1 11:12:15 UTC+0530 2010"
which in C# would translate to the following format string -
"ddd MMM d hh:mm:ss UTCzzz yyyy"
with this format string use the DateTime.ParseExact(string <Hidden Field Value>, format, provider) to get the correct value for the datetime in C#.
Use provider as System.Globalization.CultureInfo.InvariantCulture.

Resources