TIme.now and Created_At different formats? - ruby-on-rails

Ive noticed that in a model the created_at attribute when rendering a model to json has the format like:
2013-05-20T22:12:31Z
and calling Time.now and rendering to json gives a format like:
2013-05-21 00:04:03 +0000
I am trying to create a web service for an iOS app where I need to compare the current time vs the created time but cant do so because of the timezone difference.
What does the Z in the Created_at attribute represent? Is that a timezone? If so how do I change the Time.now timezone to match?
If Z is not a timezone, any recommendations?

ActiveRecord Timestamp columns (like created_at and updated_at) are loaded as the type ActiveSupport::TimeWithZone, while Time.now produces a Time. These classes have different default to_s formats, which accounts for your discrepancy.
As you guessed, both the Z and the +0000 relate to the timezone of the datetime. Your created at value is being expressed as an ISO 8601 date where Z means Zulu, another way of expressing the UTC or GMT 0-offset timezone. Good news is that means both of your dates are already in UTC.
I'm not sure what your use case is, but you should consider doing this date comparison on the server if possible instead of in the iOS client. In that case the string representation wouldn't matter since the underlying numerical values of the dates would be compared.
If you really need to do the comparison on the iOS client, then you need to explicitly format both date values when rendering the JSON so you will have a consistent representation. You'll want to do a created.strftime(...) and Time.now.strftime(...) to format the values. ISO 8601 is a good choice for date formats in an API, although you will probably want to check and see what's easiest to consume given the iOS libraries you are using.

Related

Ion DateTime also sends DateTime as UTC (Z)

My Ionic 3 app uses the ion DateTime field where the user inputs a date.
<ion-datetime displayFormat="DD/MM/YYYY HH:mm" [(ngModel)]="scheduled_at"></ion-datetime>
This gets then send to my Rails 5 API. The string that arrives at my API endpoint looks like this:
"scheduled_at"=>"2018-06-14T23:33:42.939Z"
I read that the Z indicates UTC (https://robots.thoughtbot.com/its-about-time-zones). The issue is that the timezone the user enters is not in ZTC but in 'America/Sao_Paulo', so when I parse the string to a DateTime object in Rails and store it to the DB it will always be wrong.
Is there any way to tell the ion DateTime the correct timezone?
Maybe, there is no way to do that. moment.js is an alternative.
In ionic datatime documentation,
Advanced Datetime Validation and Manipulation
The datetime picker provides the simplicity of selecting an exact
format, and persists the datetime values as a string using the
standardized ISO 8601 datetime format. However, it's important to note
that ion-datetime does not attempt to solve all situtations when
validating and manipulating datetime values. If datetime values need
to be parsed from a certain format, or manipulated (such as adding 5
days to a date, subtracting 30 minutes, etc.), or even formatting data
to a specific locale, then we highly recommend using moment.js to
"Parse, validate, manipulate, and display dates in JavaScript".
Moment.js has quickly become our goto standard when dealing with
datetimes within JavaScript, but Ionic does not prepackage this
dependency since most apps will not require it, and its locale
configuration should be decided by the end-developer.
Try to use toLocaleString() string function of Date
myDate: String = new Date().toLocaleString();

How can I change the timezone of a column in Apache Nifi?

We use Apache Nifi for our data ingestion.
We extract data from multiple sources, especially oracle databases. A lot of the extracted tables contain timestamps. As we are working in an international context, I want to change the timezone of all the timestamps into UTC time.
how can I change the timezone of a timestamp column into UTC time?
is there a generic solution, so that all timestamps are converted at once?
You can able to convert timestamp column into UTC time.
Please look at below reference website.
https://nifi.apache.org/docs/nifi-docs/html/expression-language-guide.html#format
Just consider you are having attribute named "time" which having value 1420058163264
${time:format("yyyy/MM/dd HH:mm:ss.SSS'Z'", "GMT")}
In format method you can pass your timezone which can convert timestamp into UTC Timezone.
I hope that it helps/
Thanks

Rails column type for moment.js formatted date and time

I am building a rails app, where the user picks up a date from a date picker and a time from the time picker. Both the date and time have been formatted using moment js to show the date and time in the following way:
moment().format('LL'); //January 23,2017
moment().format('LTS'); //1:17:54 PM
I read this answer with guidelines about selection of a proper column type.
Is there documentation for the Rails column types?
Ideally, I should be using :date, :time or :timestamp for this. But since the dates are formatted, should I be using :string instead?
Which would be the correct and appropriate column type to use in this situation?
If you want to store a time reference in your database you should use one of the types the database offers you. I'll explain this using MySQL (which is the one I have used the most) but the explanation should be similar in other database servers.
If you use a timestamp column you will be using just 4 bytes of storage, which is always a good new since it makes smaller indexes, uses less memory in temporal tables during the internal database operations and so on. However, timestamp has a smaller range than datetime so you will only be able to store values from year 1970 up to year 2038 more or less
If you use datetime you will be able to store a wider range (from year 1001 to year 9999) with the same precision (second). The bad consequence is that a higher range needs more memory, making it a bit slower.
There are some other differences between these two column types that don't fit in this answer, but you should keep an eye on before deciding.
If you use varchar, which is the default column type for text attributes in Ruby on Rails, you will be forced to convert from text to datetime and vice-versa every time you need to use that field. In addition, ordering or filtering on that column will be very inefficient because the database will need to convert all strings into dates before filtering or sorting, making it impossible to use indexes on that column.
If you need sub-second precision, you can use bigint to meet your requirements, as MySQL does not provide a date specific type for this purpose
In general, I recommend using timestamp if your application requirements fit the timestamp limitation. Otherwise, use datetime, but I strongly discourage you to use varchar for this purpose.
EDIT: Formatting
The way you store dates in database is completely different from the way you display it to the user. You can create a DateTime object using DateTime.new(year, month, day, hour, minute, second) and assign that object to your model. By the time you save it into database, ActiveRecord will be in charge of converting the DateTime object into the appropiate database format.
In order to display a value that is already stored in database in a specific format (in a view, API response, etc.) you can hava a look at other posts like this one.
You can have a timestamp column in your database, and then parse the request to a ruby datetime object like this:
d = Time.parse(params[:date])
t = Time.new(params[:time])
dt = DateTime.new(d.year, d.month, d.day, t.hour, t.min, t.sec, t.zone)
#now simply use dt to your datetime column
On Postgres you can save a ruby DateTime object straight into a postgres timestamp field, e.g
User.first.update_attribute('updated_at', dt )
Another option is to concatenate your date and time strings into one and then u can do a one-liner:
User.last.update_attribute('created_at', Time.parse('January 23,2017 1:17:54 PM'))
I'm pretty sure this will work on MySQL datetime or timestamp as well.
Credit to david grayson Ruby: combine Date and Time objects into a DateTime

Time zone for Firebase.ServerValue.TIMESTAMP

It appears that when I use Firebase.ServerValue.TIMESTAMP currently, it is using PDT (I assume that will be changing to PST in the fall).
Is there a way to get this in UTC instead of PDT?
Firebase timestamps are always stored as milliseconds since the epoch (midnight of 1/1/1970 in UTC). This is the same way that dates work in Javascript and many other languages. This is a timezone-agnostic way of representing time.
Generally speaking, timezone only plays a role in how a time is displayed to a user, not in how it's represented under-the-hood. Firebase timestamps are no different.
So, if you construct a JS date object using a timestamp created by Firebase.ServerValue.TIMESTAMP, it will automatically have the same timezone as the machine on which it is being displayed.

Storing DateTime in UTC

If one only works with dates and no time, would it still be wise to save all your dates in UTC for a multi timezone app?
I suggest using DateTimeOffset - this allows you to store both the DateTime and the UTC offset.
Also, read this SO question about timezone best practices.
The general the answer is yes, but it will introduce errors in time conversion if time part is not stored. Timezone conversions need time part to produce meaningful results. So just store full UTC time (i.e. date and time), since you can always trim it to just date if necessary.

Resources