Display UTC Datetime to user defined timezone - asp.net-mvc-4

I have dates in UTC in database, and I have the user timezone in their preferences table.
I have an extension method to convert from UTC to user time:
public static DateTime ToClientTime(this DateTime dt)
{
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("SA Pacific Standard Time"); //Hardcoded timezone
return TimeZoneInfo.ConvertTimeFromUtc(dt, cstZone);
}
As you can see in the code below, for now it has a hardcoded time zone name, and I should pass by parameter that value (passing the user timezone).
In CurrentThread I set the user culture, so all code in this request behaves in that culture (date formats, resources, number formats). There is a way to store the user's timezone in a global object like CurrentThread or something like that?
What I'm trying to accomplish is avoid passing the time zone to the above extension method, and instead get the timezone from a global object like CurrentThread. The extension method will be called from Controller code and also from Views.

You have a base time like UTC, right? Not you have a user specified time zone in data base. So now you can either add or subtract from the UTC time zone depending on the need.
Probably addition can provide a simple solution.
Example:
Name ----------TimeZone
------------------------
Nick ------- UTC - 6
Hary ------- UTC + 1
So, if the current UTC time is 7 PM or 18:00 then
Nick = 18-6 = 12 / 12 PM
Harry = 18+1 = 19 / 8PM

Related

Timestamp string conversion / from_utc_timestamp

I need to convert 2021-10-03 15:10:00.0 as 2021-10-03T15:10:00-04:00
I tried with.
from_utc_timestamp(from_unixtime(unix_timestamp('2021-10-03 15:10:00.0', "yyyy-MM-dd HH:mm:ss.S"),"yyyy-MM-dd'T'HH:mm:ssXXX"),"America/New_York")
I got Null value
Any suggestions please
from_utc_timestamp can accept timestamp or compatible string (yyyy-MM-dd HH:mm:ss.S), or bigint, not this: "yyyy-MM-dd'T'HH:mm:ssXXX"
Hive timestamps are timezoneless. Once you converted from UTC to America/NY, the timezone information is lost, only you know in which timezone it is, having timestamp converted it is already impossible to derive the timezone from it.
You can concatenate with timezone, conversion like this returns what you need but it works for particular date only. In December -05:00 timezone should be usedm not +04:00:
date_format(from_utc_timestamp('2021-10-03 15:10:00.0',"America/New_York"),"yyyy-MM-dd'T'HH:mm:ss+04:00") --This is wrong!!!
From_utc_timestamp is Daylight saving aware. It can be -05:00 or -04:00 depending on the date.
Consider this example, first returns 5, second returns 4:
select (unix_timestamp("2020-01-01 12:00:00.0")-unix_timestamp(from_utc_timestamp("2020-01-01 12:00:00.0","America/New_York")))/60/60
select (unix_timestamp("2020-10-19 12:00:00.0")-unix_timestamp(from_utc_timestamp("2020-10-19 12:00:00.0","America/New_York")))/60/60
So, you can get current time zone corresponding to America/New_York for the same timestamp and concatenate it with converted timestamp:
select concat(date_format(from_utc_timestamp('2021-10-03 15:10:00.0',"America/New_York"),"yyyy-MM-dd'T'HH:mm:ss"),'+0',
--get hrs shift
(unix_timestamp("2021-10-03 15:10:00.0")-unix_timestamp(from_utc_timestamp("2021-10-03 15:10:00.0","America/New_York"))) div 3600,':00')
Result:
2021-10-03T11:10:00+04:00
It should work correctly with different timestamps taking into account daylight saving time for America/New_York.

Reading and Writing UTC to TIMESTAMP in Postgresql

I have a Java application that inserts data into a database using prepared statements. In the preparedStamement date is set in UTC format.
preparedStatement.setDate(index, new java.sql.Date(date.getTime()), UTC);
I want to be sure that when read and write operations execute on the table, the response should ALWAYS be in UTC format. At the below query, when the data is read it will be converted to the client's timezone. I don't want TIME_COLUMN to be converted to any time zone. It should remain in the UTC time zone. How can I define TIME_COLUMN in that way?
Notes: I cannot edit the DB timezone. I cannot edit select queries using At time zone.
"TIME_COLUMN" TIMESTAMPTZ default (now() at time zone 'utc'),
You could set the timezone of your RDBMS to UTC, see https://medium.com/building-the-system/how-to-store-dates-and-times-in-postgresql-269bda8d6403
When that's done, whatever dates you store, they will be in UTC. Converting from UTC into something else can be done either in queries, like
select created_at at time zone 'utc' at time zone 'america/los_angeles'
from users;
Taken from https://popsql.com/learn-sql/postgresql/how-to-convert-utc-to-local-time-zone-in-postgresql
Or, you can convert the timezone at application level.

convert local time to utc and add to utc datetime moment

I have a user input where the user enters year, month and day and I create a date object
let userDate = new Date(year, month, day)
and then from a user input where the user enters minutes and hours (into variables minutes and hours)
I need to convert this date and time into UTC timestamp, using moment and I'm not sure about it. Can I just do
let utcTimestamp = moment.utc(date.toISOString()).hour(hours).minutes(minutes);
For example: if a user enters a date of 13-Mar-2018 and time of 8:45 AM (in GMT timezone), then I could use the above line of code to get UTC timestamp as I can directly add hours and minutes to the date
if a user enters a date of 13-Aug-2018 and time 8:45 (which is GMT +1, due to daylight savings time change) then with above line I might be creating a wrong date.
... I create a date object
let userDate = new Date(year, month, day)
Be careful here, you need to subtract 1 from the month, as they are numbered 0-11 by the Date instead of the usual 1-12.
and then from a user input where the user enters minutes and hours (into variables minutes and hours)
I need to convert this date and time into UTC timestamp, using moment ...
You don't need Moment for this. Just call .toISOString() on the Date object. It implicitly converts to UTC before generating the string.
var utcString = new Date(year, month-1, day, hours, minutes).toISOString();
... Can I just do
let utcTimestamp = moment.utc(date.toISOString()).hour(hours).minutes(minutes);
No, that doesn't make sense. That would only work if the date was entered in local time but the time was entered in UTC. Such a difference in behavior would surely be confusing to your user - especially if the UTC date was different than the local date.
... if a user enters a date of 13-Aug-2018 and time 8:45 (which is GMT +1, due to daylight savings time change) then with above line I might be creating a wrong date.
The conversion from local time to UTC will automatically take into account any daylight saving adjustment that is being observed by the local time zone. You do not need to do any additional adjustment on your own.
This is a snippet i used to convert an outlook calendar event from UTC to local time. The same Technique could be used for other scenarios.
//Get the users timezone
let timeZone = item.originalStartTimeZone;
//Get the start datetime in UTC time
let timeStart = item.start.dateTime;
//Calculate the negative offset.
let offset = - timeStart.localeCompare(timeZone);
//Add the calculated offset to the UTC start time
let localStartTime = addHours(timeStart, offset);

time is not saved in UTC time

Using Rails 3 and PostgreSQL 8, I have a fuel_date column with data type "timestamp without time zone". A user selects a date and time from dropdown menu in their local time and when it's submitted to server, it should be saved as UTC time:
def create_fuel_service
attributes = {}
fuel_service_hash = params[:fuel_service]
datetime = DateTime.new(fuel_service_hash["fuel_date(1i)"].to_i, fuel_service_hash["fuel_date(2i)"].to_i,
fuel_service_hash["fuel_date(3i)"].to_i, fuel_service_hash["fuel_date(4i)"].to_i,
fuel_service_hash["fuel_date(5i)"].to_i).in_time_zone(current_user.time_zone).utc
attributes[:fuel_date] = datetime
fuel_service = FuelService.new(attributes)
if fuel_service.save
...
However, the record is saved as localtime, not UTC time, even though the created_at and updated_at fields are saved as UTC time:
http://s22.postimg.org/caho7v6c1/utctime_issue.png
How can I convert the fuel_date field to UTC time before saving? Using the UTC time method of DateTime does nothing.
What ended up working was using Time.new rather than DateTime.new:
datetime = Time.new(fuel_service_hash["fuel_date(1i)"].to_i, fuel_service_hash["fuel_date(2i)"].to_i,
fuel_service_hash["fuel_date(3i)"].to_i, fuel_service_hash["fuel_date(4i)"].to_i,
fuel_service_hash["fuel_date(5i)"].to_i)

Still confused about Timezone and conversions

I collect user time zone and a time they want something delivered in that time zone.
My application is set to use Bangkok Time.
application.rb
config.time_zone = 'Bangkok'
I want to store the time the user has entered relative to my timezone.
So say for example the user selects the following:
time = "6:00"
timezone = "(GMT-10:00) Hawaii"
I want to convert this time to the time of my application and save it in the database.
How can I convert from 6AM Hawaii time zone to what time this is in Bangkok?
Let us use your example to demonstrate:
config.time_zone = 'Bangkok'
time = "6:00"
timezone = "Hawaii"
The first thing you need to do is set the timezone of your app to the timezone that the user picked:
Time.zone = "Hawaii"
You then use the this new time zone to parse time time:
hawaii_time = Time.zone.parse("6:00")
If we now print out hawaii_time we get something similar to (we have HST -10:00 which means it is correct):
Mon, 15 Aug 2011 06:00:00 HST -10:00
You now use the rails in_time_zone method to convert to your app's timezone:
local_time = hawaii_time.in_time_zone(Rails.configuration.time_zone)
If we print out local_time we'll get something similar to (we have ICT +07:00 which is correct for Bangkok):
Mon, 15 Aug 2011 23:00:00 ICT +07:00
We can now reset the timezone of our app back to its original value:
Time.zone = Rails.configuration.time_zone