I writing application using vb .net.
In my application I got text box displaying current date.
As usually after midnight date is changing.
There is any chance to set delay that date will change after 02:00 am next day ?
For example:
Today is 09/07/17 and I need that after midnight textbox will still show this date. But after 02:00 am ( 10/07/117 ) date will change for 10/07/17.
My current code:
Private Sub HOMESCREEN_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SMARTSCREEN.MdiParent = Me
SMARTSCREEN.StartPosition = FormStartPosition.CenterScreen
SMARTSCREEN.Show()
SMARTSCREEN.datee.Text = Date.Today()
SMARTSCREEN.NOWEEK.Text = (DatePart("WW", Now))
Thanks,
The big (actually huge) question is, in what time zone is that 2:00 am you're talking about? You can easily achieve that by simply changing the time zone.
Say your time zone is US Eastern Time -5, then setting the time zone in your code to US Mountain Time -7 will effectively give you the result you want.
EDIT: This is trivial, but since you mentioned that you're in UK, then I assume that your time zone is London 0, so set to Coordinated Universal Time -2 to achieve what you want.
Alternatively, it can be simpler in your code to just subtract two hours:
SMARTSCREEN.datee.Text = DateTime.Now.AddHours(-2).ToString("d")
Related
In our internal software, I'm querying the time of a task.
Because our software is based in Europe, the time is european time but I need the US one so I use the "at time zone to convert it.
To show you the problem, I've queried it twice. Onence before conversion and once after.
So the issue is that the "MM" of "HH:MM" is giving me the month instead of the minutes.
So I get 12:10(10 is the month) and I should have got 12:12 (it was 17:12 european time).
I put a screen capture of the results
Before and after
select
t.actual_start_dttm before_conversion,
to_char(cast(t.actual_start_dttm as timestamp) at time zone 'US/Eastern', 'HH:MM') after_conversion
from task t
where task_id = '695421'
You need to change the query and use 'MI' instead of 'MM'
select
t.actual_start_dttm before_conversion,
to_char(cast(t.actual_start_dttm as timestamp) at time zone 'US/Eastern', 'HH:MI') after_conversion
from task t
where task_id = '695421'
For more information you can refer below link :
https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm
https://apex.oracle.com/pls/apex/germancommunities/apexcommunity/tipp/6381/index-en.html
Minutes has Format MI not MM...
I am trying to derive a given date from a DB that is in Greenwich Mean Time. so I need to constantly account for the discrepancy.
DECLARE #date datetime
DECLARE #tempdate datetime = '3/1/2019'
SET #date = #tempdate AT TIME ZONE 'UTC' AT TIME ZONE 'Central Standard
Time'
SELECT #date
The above code produces a date several hours before March 1st (since I am in the U.S.). Is there a generic way to always grab Central Time for any desired date?
IF you are trying to convert UTC time into US Central Time it is indeed normal to receive a Central time that is earlier that UTC time. Sun rises in Greenwich first and sometime later rises in Chicago, so the March begins first in UTC zone, few hours prior to doing it in Chicago. Same goes for other months! :)
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);
I want to get timestamp of a different country in VBA. Is there any direct function or way to get it? For example, I am in India working for Mexico and I want to do certain task based on Mexican Time. I was able to get it by splitting the timestamp and manipulating it but could not consider daylight saving in it. Is there any simple solution than writing a big user-defined function?
Know your time zone offset & your client's time zone offset, then use that to calculate the difference
Dim IndiaTZ as single
Dim MexicoTZ as single
Dim MyTime as date
Dim UTC as date
Dim MexicoTime as date
IndiaTZ = 5.5
MexicoTZ = -4
'note this assumes that they're in Eastern time,
'Mexico also covers Central, Mountain & Pacific at -5, -6 & -7.
'You'll need to figure out which one you need.
MyTime = Now
'need to invert the offset to get from India to UTC
UTC = datediff("h", mytime, IndiaTZ * -1)
'need to invert the offset to get from UTC to Mexico
MexicoTime = Datediff("h", UTC, MexicoTZ * -1)
First off, I realize time with time zone is not recommended. I am going to use it because I'm comparing multiple time with time zone values to my current system time regardless of day. I.e. a user says start everyday at 08:00 and finish at 12:00 with THEIR time zone, not the system time zone. So, I have a time without time zone column in one table, let's call it SCHEDULES.time and I have a UNIX time zone name column in another table, let's call it USERS.tz.
My system time zone is 'America/Regina', which does not use DST and so the offset is always -06.
Given a time of '12:00:00' and a tz of 'America/Vancouver' I would like to select the data into a column of type time with time zone but I DO NOT want to convert the time to my time zone because the user has effectively said begin at when it is 12:00 in Vancouver, not in Regina.
Thus, doing:
SELECT SCHEDULES.time AT TIME ZONE USERS.tz
FROM SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID;
results (at the moment) in:
'10:00:00-08'
but I really want:
'12:00:00-08'
I can't find any documentation relating to applying a time zone to a time, other then AT TIME ZONE. Is there a way to accomplish this without character manipulation or other hacks?
UPDATE:
This can be accomplished by using string concatenation, casting, and the Postgres time zone view as such:
select ('12:00:00'::text || utc_offset::text)::timetz
from pg_timezone_names
where name = 'America/Vancouver';
However, this is fairly slow. There must be a better way, no?
UPDATE 2:
I apologize for the confusion. The SCHEDULES table DOES NOT use time with time zone, I am trying to SELECT a time with time zone by combining values from a time without time zone and a text time zone name.
UPDATE 3:
Thanks to all those involved for their (heated) discussion. :) I have been convinced to abandon my plan to use a time with time zone for my output and instead use a timestamp with time zone as it performs well, is more readable, and solves another problem that I was going to run into, time zones that roll into new dates. IE. '2011-11-21 23:59' in 'America/Vancouver' is '2011-11-22' in 'America/Regina'.
UPDATE 4:
As I said in my last update, I have chosen the answer that #MichaelKrelin-hacker first proposed and #JonSkeet finalized. That is, a timestamp with time zone as my final output is a better solution. I ended up using a query like:
SELECT timezone(USERS.tz, now()::date + SCHEDULES.time)
FROM SCHEDULES
JOIN USERS ON USERS.ID = SCHEDULES.USERID;
The timezone() format was rewritten by Postgres after I entered (current_date + SCHEDULES.time) AT TIME ZONE USERS.tz into my view.
WARNING: PostgreSQL newbie (see comments on the question!). I know a bit about time zones though, so I know what makes sense to ask.
It looks to me like this is basically an unsupported situation (unfortunately) when it comes to AT TIME ZONE. Looking at the AT TIME ZONE documentation it gives a table where the "input" value types are only:
timestamp without time zone
timestamp with time zone
time with time zone
We're missing the one you want: time without time zone. What you're asking is somewhat logical, although it does depend on the date... as different time zones can have different offsets depending on the date. For example, 12:00:00 Europe/London may mean 12:00:00 UTC, or it may mean 11:00:00 UTC, depending on whether it's winter or summer.
On my system, having set the system time zone to America/Regina, the query
SELECT ('2011-11-22T12:00:00'::TIMESTAMP WITHOUT TIME ZONE)
AT TIME ZONE 'America/Vancouver'
gives me 2011-11-22 14:00:00-06 as a result. That's not ideal, but it does at least give the instant point in time (I think). I believe that if you fetched that with a client library - or compared it with another TIMESTAMP WITH TIME ZONE - you'd get the right result. It's just the text conversion that then uses the system time zone for output.
Would that be good enough for you? Can you either change your SCHEDULES.time field to be a TIMESTAMP WITHOUT TIME ZONE field, or (at query time) combine the time from the field with a date to create a timestamp without time zone?
EDIT: If you're happy with the "current date" it looks like you can just change your query to:
SELECT (current_date + SCHEDULES.time) AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID
Of course, the current system date may not be the same as the current date in the local time zone. I think this will fix that part...
SELECT ((current_timestamp AT TIME ZONE USERS.tz)::DATE + schedules.time)
AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID
In other words:
Take the current instant
Work out the local date/time in the user's time zone
Take the date of that
Add the schedule time to that date to get a TIMESTAMP WITHOUT TIME ZONE
Use AT TIME ZONE to apply the time zone to that local date/time
I'm sure there's a better way, but I think it makes sense.
You should be aware that in some cases this could fail though:
What do you want the result to be for a time of 01:30 on a day when the clock skips from 01:00 to 02:00, so 01:30 doesn't occur at all?
What do you want the result to be for a time of 01:30 on a day when the clock goes back from 02:00 to 01:00, so 01:30 occurs twice?
Here is a demo how to calculate the times without casting to text:
CREATE TEMP TABLE schedule(t time, tz text);
INSERT INTO schedule values
('12:00:00', 'America/Vancouver')
,('12:00:00', 'US/Mountain')
,('12:00:00', 'America/Regina');
SELECT s.t AT TIME ZONE s.tz
- p.utc_offset
+ EXTRACT (timezone from now()) * interval '1s'
FROM schedule s
JOIN pg_timezone_names p ON s.tz = p.name;
Basically you have to subtract the UTC offset and add the offset of your local time zone to arrive at the given time zone.
You can speed up the calculation by hardcoding your local offset. In your case (America/Regina) that should be:
SELECT s.t AT TIME ZONE s.tz
- p.utc_offset
- interval '6h'
FROM schedule s
JOIN pg_timezone_names p ON s.tz = p.name;
As pg_timezone_names is a view and not actually a system table, it is rather slow - just like the demonstrated variant with casting to text representation and back.
I would store the time zone abbreviations and take the double cast via text without joining in pg_timezone_names for optimum performance.
FAST solution
The culprit that's slowing you down is pg_timezone_names. After some testing I found that pg_timezone_abbrevs is far superior. Of course, you have to save correct time zone abbreviations instead of time zone names to achieve this. Time zone names take DST into consideration automatically, time zone abbreviations are basically just codes for a time offset. The documentation:
A time zone abbreviation, for example PST. Such a specification merely
defines a particular offset from UTC, in contrast to full time zone names
which can imply a set of daylight savings transition-date rules as well.
Have a look at these test results or try yourself:
SELECT * FROM pg_timezone_names;
Total runtime: 541.007 ms
SELECT * FROM pg_timezone_abbrevs;
Total runtime: 0.523 ms
Factor 1000. Whether you go with your idea to cast to text and back to timetz or with my method to compute the time is not important. Both methods are very fast. Just don't use pg_timezone_names.
Actually, as soon as you save time zone abbreviations, you can take the casting route without any additional joins. Use the abbreviation instead of the utc_offset. Results are accurate as per your definition.
CREATE TEMP TABLE schedule(t time, abbrev text);
INSERT INTO schedule values
('12:00:00', 'PST') -- 'America/Vancouver'
,('12:00:00', 'MST') -- 'US/Mountain'
,('12:00:00', 'CST'); -- 'America/Regina'
-- calculating
SELECT s.t AT TIME ZONE s.abbrev
- a.utc_offset
+ EXTRACT (timezone from now()) * interval '1s'
FROM schedule s
JOIN pg_timezone_abbrevs a USING (abbrev);
-- casting (even faster!)
SELECT (t::text || abbrev)::timetz
FROM schedule s;