What is meaning of PT and S in values returned from Microsoft get call records api? [duplicate] - call

I am trying to use the Duration class instead of long.
It has superior literal syntax. I like its flexibility, though it looks weird.
"PT10S" means 10 seconds, what is the problem to accept "10 seconds"?!
Okay never mind.
I am just curious why PT prefix has been chosen (not "DU" e.g.) and why any prefix is better here rather than nothing?

As can be found on the page Jesper linked to (ISO-8601 - Data elements and interchange formats – Information interchange – Representation of dates and times)
P is the duration designator (for period) placed at the start of the duration representation.
Y is the year designator that follows the value for the number of years.
M is the month designator that follows the value for the number of months.
W is the week designator that follows the value for the number of weeks.
D is the day designator that follows the value for the number of days.
T is the time designator that precedes the time components of the representation.
So P means 'Period' and because there are no date-components it only has a 'Time'.
You could interpret this as 'Period of Time'
The 'why' this was chosen, you have to ask the ISO members that wrote the standard, but my guess is that it is easier to parse. (short and unambigious)
The details for the time component are:
H is the hour designator that follows the value for the number of hours.
M is the minute designator that follows the value for the number of minutes.
S is the second designator that follows the value for the number of seconds.
The value of PT20S then parses to:
Period
Time
20
Seconds
So, a duration of 20 seconds.
More examples can be found in the javadoc: https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-

Java has taken a subset of the ISO 8601 standard format for a duration. So the “why” is why the standard was written the way it is, and it’s a guessing game. My go is:
P for period was chosen so that you can distinguish a duration from a date and/or time. Especially since a period may also be written in the same format as a local date-time, for example P0003-06-04T12:30:05 for 3 years 6 months 4 days 12 hours 30 minutes 5 seconds, the P can be necessary to distinguish. The P also gives a little but quick and convenient bit of validation in case you happen to pass a completely different string in a place where a duration was expected. And yes, PT10S looks weird, but once you get accustomed to it, you recognize it immediately as a duration, which can be practical.
T for time between the date part and the time part was chosen for two reasons:
For consistency with date-time strings that have T in the same place, for example 2018-07-04T15:00 for July 4, 2018 at 15:00 hours.
To disambiguate the otherwise ambiguous M for either months or minutes: P3M unambiguously means 3 months while PT3M means 3 minutes.

Actually if go on Duration API developed in Java since 1.8, they have gone with standard ISO 8601:
with java doc as below :
/**
* Applies an ISO 8601 Duration to a {#link ZonedDateTime}.
*
* <p>Since the JDK defined different types for the different parts of a Duration
* specification, this utility method is needed when a full Duration is to be applied to a
* {#link ZonedDateTime}. See {#link Period} and {#link Duration}.
*
* <p>All date-based parts of a Duration specification (Year, Month, Day or Week) are parsed
* using {#link Period#parse(CharSequence)} and added to the time. The remaining parts (Hour,
* Minute, Second) are parsed using {#link Duration#parse(CharSequence)} and added to the time.
*
* #param time A zoned date time to apply the offset to
* #param offset The offset in ISO 8601 Duration format
* #return A zoned date time with the offset applied
*/
public static ZonedDateTime addOffset(ZonedDateTime time, String offset) { }
Obtains a Duration from a text string of pattern: PnDTnHnMn.nS, where
nD = number of days,
nH = number of hours,
nM = number of minutes,
n.nS = number of seconds, the decimal point may be either a dot or a comma.
T = must be used before the part consisting of nH, nM, n.nS
Example of implementation with java as
import java.time.Duration;
public class ParseExample {
public static void main(String... args) {
parse("PT20S");//T must be at the beginning to time part
parse("P2D");//2 day
parse("-P2D");//minus 2 days
parse("P-2DT-20S");//S for seconds
parse("PT20H");//H for hours
parse("PT220H");
parse("PT20M");//M for minutes
parse("PT20.3S");//second can be in fraction like 20.3
parse("P4DT12H20M20.3S");
parse("P-4DT-12H-20M-20.3S");
parse("-P4DT12H20M20.3S");
}
private static void parse(String pattern) {
Duration d = Duration.parse(pattern);
System.out.println("Pattern: %s => %s%n", pattern, d);
}
}

Related

Postgres Date Type Value

Want to retrieve a date type from a postgres table using liqpq PQexecParams() in binary mode (please humor me).
https://www.postgresql.org/docs/14/datatype-datetime.html says that a date is 4 bytes (4713 BC to 5874897 AD).
src/include/utils/date.h defines:
typedef int32 DateADT;
But obviously given the supported date range it's not a normal int. Something like this:
int32_t haha = be32toh(*((uint32_t *) PQgetvalue(res, 0, 17)));
Gives haha=1466004328 for 2022-10-25.
Which is clearly not a day count and since its not a ratio of 86,400 is also not seconds since an epoch. Number is also too small to be microseconds.
How do I interpret the 4 bytes of postgresql 'date' data?
Added Later:
This question contains an error - PQgetvalue() references column 17 (a text value) instead of column 18 (a date value) - with that corrected haha=8332
Date is an integer day count from POSTGRES_EPOCH_JDATE (2000-01-01).

Cant get right localtime in C

Im trying to get the current localtime in C, lets say Italy, I tried the code below but it returns a time three hours earlier than the real one.
For example if executed at 17:34 it will return 14:34, what am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
setenv("TZ", "UTC+1", 1); // Italy is UTC+1
tzset();
time_t sec = 1634224877; // Just for test
struct tm * end = localtime(&sec);
// Check for daylight save
if(end->tm_isdst == 1)
{
end->tm_hour += 1;
}
printf("Daylight save time?: %d\n", end->tm_isdst);
printf("Time is says: %.2d/%.2d/%d - %.2d:%.2d:%.2d\n", end->tm_mday, end->tm_mon + 1, end->tm_year + 1900,
end->tm_hour, end->tm_min, end->tm_sec);
}
Thanks
tl;dr If you want the time at a location, you have to set TZ to a location.
1634224877 is 2021-10-14 15:21:17 UTC. setenv takes POSIX time zones which don't work like you think. UTC+1 means one hour head of UTC. That is 14:21:17. If you want "UTC+1" you actually ask for UTC-1, one hour behind UTC.
But don't ask for UTC-1.
setenv("TZ", "UTC+1", 1); // Italy is UTC+1
That comment is not correct. Italy is not UTC+1. Sometimes Italy is UTC+1, sometimes it is UTC+2. In order to know about daylight savings time (and other wacky time zone issues), TZ needs to know your location.
Set TZ to the city closest to you, like Europe/Rome. Now localtime can figure out whether it's daylight savings time or not, you do not need to correct it.
int main()
{
setenv("TZ", "Europe/Rome", 1);
tzset();
time_t sec = 1634224877; // Just for test
struct tm * end = localtime(&sec);
printf("Daylight savings time?: %d\n", end->tm_isdst);
printf("Time is says: %.2d/%.2d/%d - %.2d:%.2d:%.2d\n", end->tm_mday, end->tm_mon + 1, end->tm_year + 1900,
end->tm_hour, end->tm_min, end->tm_sec);
}
Daylight savings time?: 1
Time is says: 14/10/2021 - 17:21:17
The system that manages time zones is called tzdata. It is a database of locations, their time zone information, daylight savings time switches, and a host of other wacky time zone information. It's what lets your computer know that Rome is usually UTC+1 but should sometimes be UTC+2.
A list of all tzdata locations can be had on Wikipedia, but these do not necessarily match the tzdata installed on your machine.
The TZ environment variable value FOO+1 (I changed it from UTC+1 to avoid confusion) is interpreted as a standard time zone designated "FOO" with no alternate (daylight savings) zone. The +1 (the + is optional) means that 1 hour needs to be added to the local time to convert it to Coordinated Universal Time (UTC). To specify an alternate (daylight savings) time zone, it is added after the standard time offset, e.g. FOO+1BAR0. The offset after the alternate zone can be omitted in which case it defaults to one less than the standard offset, so FOO+1BAR0 can be shortened to FOO1BAR. This means that local time will be 1 hour behind UTC when standard time is in effect and will be UTC when alternate (daylight savings) time is in effect. Optionally, the offset can include minutes or minutes and seconds, e.g. FOO+01:00BAR+00:00:00.
Italy uses Central European Time (CET, corresponding to UTC+1) when standard time is in effect (e.g. during winter), and uses Central European Summer Time (CEST, corresponding to UTC+1) when alternate (daylight savings) time is in effect (e.g. during summer). That can be expressed by the TZ environment variable value CET-1CEST-2 or CET-1CEST. Notice that the offsets used in the TZ environment variable have the opposite sign to the usual convention.
When TZ has one of the previously mentioned values with an alternate time (e.g. CET-1CEST), it is left up to the system libraries to use some arbitrary (and usually incorrect for most of the world) rule to determine the date and time of transitions between standard time and alternate time. Simple rules for the date and time of exactly two transitions per year can be encoded after the alternate zone designation and offset in the TZ variable, separated by commas. The transition date can be specified as Mm.n.d, meaning the dth day (0 = Sunday, 1 = Monday, ..., 6 = Saturday) of the nth week (counting from 1) of the mth month (1 = January, ..., 12 = December). n = 5 is interpreted as the last d day of the month m. The transition date can also be specified as Jn where n is the day of the year, not counting February 29 (so March 1 is always day 60). The (optional) transition time can be specified as /time, where time specifies the current local time on the transition date at which the transition to the other time is made, defaulting to 02:00:00. The time value can be abbreviated in the same way as time zone offsets, so /2 is the same as /02:00:00, but no leading plus or minus sign is allowed (by the current standard).
Italy currently operates on EU time zone transition rules (the abolition of which is currently postponed), where the transitions occur at 01:00 UTC and local time advances 1 hour on the last Sunday of March (M3.5.0) and retreats 1 hour on the last Sunday of October (M10.5.0). For Italy, the local transition times are 02:00:00 in March (advancing to 03:00:00) and 03:00:00 in October (retreating to 02:00:00), so the rules are M3.5.0/2 and M10.5.3. (M3.5.0/2 can be shortened to M3.5.0 since it uses the default transition time.)
The following, modified code will work to show time in Italy, at least until the current EU time zone rules are abolished:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1); // Italy rules!
tzset();
time_t sec;
#if 0
sec = 1634224877; // Just for test
#else
sec = time(NULL); // For current time
#endif
struct tm * end = localtime(&sec);
printf("Daylight save time?: %d\n", end->tm_isdst);
printf("Time is says: %.2d/%.2d/%d - %.2d:%.2d:%.2d\n",
end->tm_mday, end->tm_mon + 1, end->tm_year + 1900,
end->tm_hour, end->tm_min, end->tm_sec);
}

Converting 'date' stored as integer (number of days since 1 Jan 1970) in Avro to Snowflake 'date' type

I've a requirement to migrate data from some on-premise databases to the cloud. Some of the data in the tables is stored as 'date' in format yyyy-mm-dd.
We are converting the data stored in the tables into Avro format and then it's copied into Snowflake.
In Avro, date is stored as an integer Avro Date type
When I try to push the data into snowflake, it's unable to convert that integer back into date. I get the following error: 'Failed to case VARIANT 13707 to date'
where 13707 is number of days since Jan 1 1970
Thanks!
You need to calculate the date value based on the variant value. You can use DATEADD for this purpose:
https://docs.snowflake.com/en/sql-reference/functions/dateadd.html
create table avro_test ( x date );
insert into avro_test(x)
select dateadd('day',parse_json('13707'),'1970-01-01');
select * from avro_test;
+------------+
| X |
+------------+
| 2007-07-13 |
+------------+
If the format of the input parameter is a string that contains an integer:
After the string is converted to an integer, the integer is treated as a number of seconds, milliseconds, microseconds, or nanoseconds after the start of the Unix epoch (1970-01-01 00:00:00.000000000 UTC).
If the integer is less than 31536000000 (the number of milliseconds in a year), then the value is treated as a number of seconds.
If the value is greater than or equal to 31536000000 and less than 31536000000000, then the value is treated as milliseconds.
If the value is greater than or equal to 31536000000000 and less than 31536000000000000, then the value is treated as microseconds.
If the value is greater than or equal to 31536000000000000, then the value is treated as nanoseconds.
If more than one row is evaluated (for example, if the input is the column name of a table that contains more than two rows), the first processed value determines whether all subsequent values are treated as seconds, milliseconds, microseconds, or nanoseconds.
If the first value is greater than or equal to 31536000000, then all values will be treated as milliseconds, even if some remaining values are less than 31536000000. Similar logic applies for microseconds and nanoseconds.

GMT subtraction on MATLAB

I'm currently working on a small project on handling time difference on MATLAB. I have two input files; Time_in and Time_out. The two files contain arrays of time in the format e.g 2315 (GMT - Hours and Minute)
I've read both Time_in' and 'Time_out on MATLAB but I don't know how to perform the subtraction. Also, I want the corresponding answers to be in minutes domain only e.g (2hrs 30mins = 150minutes)
this is one of several possible solutions:
First, you should convert your time strings to a MATLAB serial date number. If you've done this, you can do your calculation as you want:
% input time as string
time_in = '2115';
time_out = '2345';
% read the input time as datenum
dTime_in = datenum(time_in,'HHMM');
dTime_out = datenum(time_out,'HHMM');
% subtract to get the time difference
timeDiff = abs(dTime_out - dTime_in);
% Get the minutes of the time difference
timeout = timeDiff * 24 * 60;
Furthermore, to calculate the time differences correctly you also should put some information about the date in your time vector, in order to calculate the correct time around midnight.
If you need further information about the function datenum you should read the following part of the MATLAB documentation:
https://de.mathworks.com/help/matlab/ref/datenum.html
Any questions?
In a recent version of MATLAB, you could use textscan together with datetime and duration data types to do this.
% read the first file
fh1 = fopen('Time_in');
d1 = textscan(fh1, '%{HHmm}D');
fclose(fh1);
fh2 = fopen('Time_out');
d2 = textscan(fh2, '%{HHmm}D');
fclose(fh2);
Note the format specifier '%{HHmm}D' tells MATLAB to read the 4-digit string into a datetime array.
d1 and d2 are now cell arrays where the only element is a datetime vector. You can subtract these, and then use the minutes function to find the number of minutes.
result = minutes(d2{1} - d1{1})

How to generate a specific time of clock in "C" programming [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
For example, the following are sample runs of the program:
Enter the hour: 5
Enter the minute: 23
Enter A (for AM) or P (for PM): A
Enter how many minutes to display: 5
The new time is
5:24 AM
5:25 AM
5:26 AM
5:27 AM
5:28 AM
Enter the hour: 11
Enter the minute: 57
Enter A (for AM) or P (for PM): P
Enter how many minutes to display: 4
The new time is
11:58 PM
11:59 PM
12:00 AM
12:01 AM
Enter the hour: 12
Enter the minute: 55
Enter A (for AM) or P (for PM): P
Enter how many minutes to display: 7
The new time is
12:56 PM
12:57 PM
12:58 PM
12:59 PM
1:00 PM
1:01 PM
1:02 PM
Also, I'm not allowed to use the folling statements:
• break; (except when used in a switch() statement)
• continue;
• exit();
• abort();
• goto
I will preface this by answer by stating that using the in-built C time functions is overkill for this problem, which is unfortunately the kind of intuition that you only gain from experience.
From the problem statement, you can deduce that you require a "time" value that can represent 24 hours worth of time, at one minute granularity. The operations required on this time value are:
Set the value to a time provided by the user, as an "hour" value, a "minute" value, and an "AM/PM" value;
Output the value in the format "11:58 PM";
Add a minute to the time value.
You now have to decide how you're going to represent the "time" value in C. One option is to use two integers (representing the hour and the minute) and a boolean (representing AM or PM). When you use multiple values to represent a single logical value, it's conventional to wrap those into a struct, so our "time" type might look like:
struct time_of_day {
int hour; /* From 1 to 12 */
int minute; /* From 0 to 60 */
int is_pm; /* 0 or 1 */
};
(In this case we've followed the convention that an int is used to store a boolean value).
You now have to figure out how to implement the three operations above using this representation of a time. With this representation, the first operation Set the value to a time provided by the user becomes very easy: you simply need to check that the hour and minute values provided are in the correct range, then store them directly in the hour and minute members of the struct time_of_day. You then need to set the is_pm value to 0 if the user entered "AM", or 1 if the user entered "PM".
The second operation Output the value is also quite simple: you can directly use the printf(), if you know these hints:
The printf format specifier %.2d will print an integer padded to two places;
The expression is_pm ? "PM" : "AM" will evaluate to "PM if is_pm is true, and "AM" if it is not.
The third operation, Adding a minute to the time value, can be broken down like this:
Add 1 to the minute part of the time;
If the minute part is now less than 60, stop;
Set the minute part to 0 and add 1 to the hour part of the time;
If the hour part is now less than 12, stop;
If the hour part is now 12, change from AM to PM or PM to AM and stop;
Set the hour part to 1.
An additional hint for this part:
The expression is_pm = !is_pm will change is_pm from 0 to 1 and 1 to 0.
I'd say the simplest method is to use strftime(), see MSDN details. You'll have to manually do the multiple time outputs, but it's a simple enough process once you've filled in the tm struct.

Resources