startOfDay date converted when printed - swift

I'm in a GMT+1 timezone.
Function startOfDay should return "the first moment of the given date".
In my case for date "2020-11-10 19:52:52 +0000\n" I should get "2020-11-10 00:00:00 +0000\n", but I'm getting "2020-11-09 23:00:00 +0000\n" (desired time - 1 hour).
As you can see in the screenshot, variable is set up correctly, but when I try to print it, it is magically converted. It looks like swift is converting it on the fly, but why?
At first, I thought that maybe somehow I have different timezone for Calendar object, but when I print Calendar.current.timeZone.abbreviation() the result is "GMT+1", same as for Date object or TimeZone.current.abbreviation().
Xcode playground

Related

Why is [datetime] converting this UTC time correctly and how can I replicate that with ParseExact

I feel silly that I cannot figure this one out on my own.
I have dates coming from the CarbonBlack API e.g. 2022-02-15-172040 which are in UTC
The [datetime] type cast works fine if I remove the seconds portion of the string
PS M:\Scripts> [datetime]"2022-02-15-1720"
Tuesday, February 15, 2022 12:20:00 PM
I don't understand how it "knows" that is a UTC string. It is correct of course but I expected 5:20pm for the time portion. I wanted the seconds for the date so I went to parse exact as this doesn't match any format strings as far as I know
PS M:\Scripts> [datetime]::ParseExact("2022-02-15-172040", "yyyy-MM-dd-HHmmss" ,[Globalization.CultureInfo]::CurrentUICulture)
Tuesday, February 15, 2022 5:20:40 PM
Which is the time I expected but the incorrect time.
Why is the [datetime] working when I wouldn't expect it to and what do I need to do to the string or static method call for it to treat that as a UTC string with minimal manipulation?
This is because
([datetime]"2022-02-15-1720").Kind
yields 'Local', while
([datetime]::ParseExact("2022-02-15-172040", "yyyy-MM-dd-HHmmss",[CultureInfo]::InvariantCulture)).Kind
returns 'Unspecified'
If you want the result to handle the string as being Local time and then the result should be in UTC, use:
([datetime]::ParseExact("2022-02-15-172040", "yyyy-MM-dd-HHmmss",[CultureInfo]::InvariantCulture, 'AssumeLocal')).ToUniversalTime()
or
$date = [datetime]::ParseExact("2022-02-15-172040", "yyyy-MM-dd-HHmmss",[CultureInfo]::InvariantCulture)
[datetime]::SpecifyKind($date, 'Local').ToUniversalTime()
Going the other way around, so if you regard the date in the string represents UTC (Universal Time), and you want the result to be in
Local time , you need to do this:
[datetime]::ParseExact("2022-04-29-185121", "yyyy-MM-dd-HHmmss",[CultureInfo]::InvariantCulture, 'AssumeUniversal')
Here, ParseExact() treats the string as UTC and outputs a date converted to Local time
(.Kind --> 'Local'), which is the exact same output as
[datetime]"2022-04-29-1851"
would give: also here, .Kind --> 'Local'`
If then you want the resulting date to be in UTC, you need to convert it back again with .ToUniversalTime()
The tricky part is that using ParseExact() without the third parameter ('AssumeLocal' or 'AssumeUniversal') when parsing a string that has no
indication of it being Local or UTC like the example strings here, is always returning a datetime object with its .Kind property set to Unspecified.
Thanks to mklement0's comment,
in PowerShell (Core) 7+, strings like in the example are no longer recognized and should have a TimeZone indication like '2022-02-15 17:20Z'. ('Z' --> Zulu (UTC) Time)
If you do give it the third parameter, telling it what timezone it should use ('AssumeLocal' or 'AssumeUniversal'), the resulting datetime object will
always have its .Kind property set to Local and the result will be converted to local time in case you have given AssumeUniversal as parameter.

How to get a specific date of next month? (Java 8)

With today's date, I should get the 16th date of next month.
For example, on passing 13-12-2021, I should get 16-01-2022.
I need to get the next month 16th day from current date (input date). Examples:
On passing 13-11-2021 should get 16-12-2021.
On passing 14-11-2021 should get 16-12-2021.
On passing 15-11-2021 should get 16-12-2021.
On passing 02-12-2021 should get 16-01-2022.
On passing 03-12-2021 should get 16-01-2022.
On passing 03-01-2022 should get 16-02-2022.
On passing 04-01-2022 should get 16-02-2022.
Any help will be much appreciated. Thanks.
java.time
One of the many strong points of java.time, the modern Java date and time API, is date arithmetic like this.
public static LocalDate nthDayOfFollowingMonth(
int desiredDayOfMonth, LocalDate currentDate) {
return YearMonth.from(currentDate)
.plusMonths(1)
.atDay(desiredDayOfMonth);
}
Try it out with your example date:
System.out.println(nthDayOfFollowingMonth(
16, LocalDate.of(2021, Month.DECEMBER, 13)));
Output:
2022-01-16
We might not have needed to convert to YearMonth and back to LocalDate. Doing so relieves both me and the reader of considering what happens if today’s day of month doesn’t exist in next month — for example if current date is 30 January (there is no 30 February). What one still wants to consider is what happens if you request a day of month tht doesn’t exist next month. For example on 13 January asking for the 30th of next month. We can try that out too:
System.out.println(nthDayOfFollowingMonth(
30, LocalDate.of(2022, Month.JANUARY, 13)));
I find the result very reasonable:
java.time.DateTimeException: Invalid date 'FEBRUARY 30'

setDate not setting date properly inside eval in batch script

--eval "var date = new Date(); date.setDate(date.getDate()-10)"'
pause
new Date() gives me the current date. I'm trying to get 10 days back date,but setDate() not setting the date correctly.I'm doing it through batch script.
I got this 1576031482772 after evaluating date.setDate(date.getDate()-10) .Please help me find a solution.
This is the expected behavior. The signature of setDate is as follows. ref
Parameters
It accepts one parameter, it should be number as a day value.
Return Value
It returns milliseconds between 1 January 1970 00:00:00 UTC and the given date
Solution
You are actually setting the day value of date. So If you want to retrieve the value, just use date.getDate(). Which will be the new date.
For more details, how it works, you can refer MDN.

Same unixtime yields different date time in joda than the correct date time

I read from a very old post here on stackoverflow that joda is a possible solution to convert Unix timestamp.
import org.joda.time._
new DateTime(1511544070).toString("yyyy-MM-dd")
I got 1970-01-18 for this case, however, this is wrong because the date should be
according to this online converter: 11/24/2017 # 5:21pm (UTC)
It is possible the online converter is correct because the sample unix timestamp 1511544070 is from a dataset that date range is November 25 to December 03, 2017, the dataset is from China time which is 8 hours ahead of UTC, meaning 11/24/2017 # 5:21pm (UTC) is actually 11/25/2017 # 1:21am (Beijing Time)
Where can I get a working library or is there a working library that can get the same result like the online converter?
You can do that using java.time:
import java.time.{ LocalDateTime, ZoneOffset }
import java.time.format.DateTimeFormatter
LocalDateTime.ofEpochSecond(1511544070, 0, ZoneOffset.UTC)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd # h:mm a"))
Looking at the documentation for joda-time we see that a DateTime can take a Long specifying the milliseconds since 1 Jan 1970. However, you seem to be providing a value in seconds. Joda-time is actually calculating it correctly, since since 1511544070/(1000*3600*24) equals 17.49 days, i.e. 1970-01-18.
To get the expected result multiply with 1000:
new DateTime(1511544070*1000).toString("yyyy-MM-dd")
To get the time in another timezone, add withZone() as follows (for Shanghai/Beijing):
new DateTime(1511544070*1000).toString("yyyy-MM-dd")
.withZone(DateTimeZone.forID("Asia/Shanghai"))

Powershell simplest method to get current time expressed as UTC

I have reviewed the post Creating a DateTime object with a specific UTC DateTime in PowerShell, but it does not seem to directly answer the question I am asking:
What is the most direct method in PowerShell (3.0) to return a sortable string representing "now" as UTC?
I expected the correct answer to be:
Get-Date -Format (Get-Culture).DateTimeFormat.UniversalSortableDateTimePattern
OR
get-date -format u
but this is not the case.
Example: At 1300 hrs (1pm) on September 1st, 2016 in the Pacific Time Zone during DST, I get the response:
2016-09-01 13:00:00Z (the local time with a "Z" appended)
when I was expecting:
2016-09-01 20:00:00Z (correct UTC/GMT time)
So basically, my code is just getting a string representing the "local" time and appending a "Z".
Now, I know I can manipulate to get to that point, but I'm looking for the minimal (simplest, cleanest) way to get here.
Bonus Points (as if they existed): How do I get that same, sortable result, but displaying with "UTC" and/or "GMT" as the suffix. Same minimal requirement.
Probably something like this:
[DateTime]::UtcNow.ToString('u')
Which is equivalent to:
[DateTime]::UtcNow.ToString((Get-Culture).DateTimeFormat.UniversalSortableDateTimePattern)
For the bonus, I think the most straightforward way is just to replace Z with UTC:
[DateTime]::UtcNow.ToString('u').Replace('Z','UTC')
I'm assuming you'll always want UTC since that what it seems like from your question. There doesn't appear to be a format string to get just the 3 letter time zone.
I tried this, and it also gives the result I want:
"[DateTime]::UtcNow.ToString('yyyyMMdd_HHmmss_UTC')"
It is showing time in the format 20180108_152407_UTC
so you can play with the date/time formatting as you wish basically