UIDatePicker modal view show incorrect (last) month - swift

My UIDatePicker (with style .compact) is set to Today by default, and always in timezone UTC.
cell.datePicker.subviews[0].backgroundColor = nil
cell.datePicker.backgroundColor = .secondarySystemGroupedBackground
cell.datePicker.timeZone = TimeZone(identifier: "UTC")
cell.datePicker.date = flight.date
cell.datePicker.addTarget(self, action: #selector(handleDatePicker(sender:)), for: UIControl.Event.valueChanged)
After clicking on the textfield "Jan 11, 2023", it will show a calendar-style editor. However, the date was set to today (Jan 11, 2023), but it shows the month of "December 2022" initially.
After I click the arrow (next month), the date (Jan 11) was pre-selected correctly.
The expected behavior should be after clicking the text "Jan 11, 2023", the month of "Jan 2023" is shown with Jan 11 pre-selected.
This bug can only be re-produced if the date is set to "today", but the UTC date and the local date are different.
For example, I'm in UTC+8 timezone. The date is set to "2023-01-11 17:30:00 +0000". When the UTC time is Jan 11, 2023 17:30Z, and the local time is Jan 12, 2023 01:30L. It will show "December 2022" when the modal view first shown.

Related

Text DateStyle with short month name in SwiftUI

The following outputs the complete month name, e.g. July 11, 2022
Text("\(Date().now, style: .date)") // output: July 11, 2022
Is there a way to make it show just the short month name, e.g. Jul 11, 2022 or 06/11/22?
Show current date without time in a short format.
//Jul 11, 2022
Text(Date().formatted(date: .abbreviated, time: .omitted))
//7/11/2022
Text(Date().formatted(date: .numeric, time: .omitted))
SwiftUI 3+
We have now explicit initializer for that, like
Text(Date.now, format: Date.FormatStyle(date: .abbreviated, time: .omitted))

Crystal Reports - If date field is greater than today then today else date field

I am working on a contract and need a date to be the current date if {month3} is after the current date.
I have tried it every way imaginable, I have 2 scenarios where if {month3} is after the current date it prints {month3}, but if {month3} is prior to the current date it prints the current date and hides part of the text above it.
It works on one but not the other, Go easy on me, it's my first post!
IF TOTEXT({Month3},"MMMM dd, yyyy") >= TOTEXT((Currentdate),"MMMM dd, yyyy") THEN
TOTEXT((Currentdate),"MMMM dd, yyyy")
ELSE
TOTEXT({Month3},"MMMM dd, yyyy")
{Month 3} = 7/30/2020
From contract signing to July 30, 2020
From July 07, 2020 to the start of the official event date
the other one is right
{month3} = 5/18/20
Top sentence is hidden and it says:
From July 07, 2020 to the start of the official event date
It's because you compare text-strings instead of dates. Remove the TOTEXT-function and set the date format directly on the properties of the formula field.
IF {Month3} >= Currentdate THEN
Currentdate
ELSE
{Month3}

Swift Date Components .day is being ignored

I'm trying to find the first day of the month. There have been different solutions posted here on SO (e.g. this)
When analyzing them it seems like the day component is being ignored.
Instead of returning the first day of the month
Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!
it returns the current day but changes the month:
(lldb) po Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!
▿ 2019-02-28 23:00:00 +0000
- timeIntervalSinceReferenceDate : 573087600.0
(lldb) po self
▿ 2019-03-28 01:09:17 +0000
- timeIntervalSinceReferenceDate : 575428157.663583
I've also looked into setting the components by hand:
var components = Calendar.current.dateComponents([.year, .month, .day], from: self)
components.setValue(1, for: .day)
let value = Calendar.current.date(from: components)!
which results in the same:
(lldb) po value
▿ 2019-02-28 23:00:00 +0000
- timeIntervalSinceReferenceDate : 573087600.0
Am I doing something wrong? Or is this a bug in Calendar?
Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.6.0
Oh in case this is interesting I'm developing for macOS but as far as I can see, this API is not influenced by Catalina.
Your code is fine. You have a date that is in March 2019. You create a new date that is March 1, 2019 at midnight local time. All good so far.
The only issue is your misunderstanding of the output of printing that date. The date is printed in the debugger in UTC time. That's what the +0000 means - UTC time. You must live in the UTC+1 timezone.
So March 1, 2019 at midnight your local time is the same as February 28, 2019 at 23:00 UTC. It's the same moment in time, just displayed in a different timezone.
In short, your code is fine.

Printing in console Date() giving incorrect current time [duplicate]

This question already has answers here:
NSDate() or Date() shows the wrong time
(2 answers)
Closed 4 years ago.
I created an object that has a creation date property. The date property is calculated by using the Date() function, for getting the current date and time.
The date is correct but the time is 3 hours behind the clock of the simulator. How can I fix this?
The system displays the current date / time of UTC/GMT.
To get time/date for local time zone. use following code:
let currentDate = Date()
//7/29/18, 9:09 PM
print (DateFormatter.localizedString(
from: currentDate,
dateStyle: .short,
timeStyle: .short))
//Sunday, July 29, 2018 at 9:09:27 PM India Standard Time
print (DateFormatter.localizedString(
from: currentDate,
dateStyle: .full,
timeStyle: .full))
//Jul 29, 2018 at 9:09:27 PM
print (DateFormatter.localizedString(
from: currentDate,
dateStyle: .medium,
timeStyle: .medium))
Above code is tested in India at 09:09 PM on 29th July 2018.

Subtracting 2 Dates using DateComponents gives undefined behavior

Given the following method I added to the Date object in an extension:
extension Date {
static func -(left: Date, right: Date) -> DateComponents {
let components: Set<Calendar.Component> = [
.year,
.month,
.day,
.hour,
.minute,
.second,
//.weekOfYear, // issue!
]
let gregorian = Calendar(identifier: .gregorian)
let dateComponents = gregorian.dateComponents(components, from: right, to: left)
return dateComponents
}
}
And given the following dates (format is Month Day, Year, hh:mm:ss) you get 1:
let day1 = Date(timeIntervalSince1970: 1516003200) // January 15, 2018, 00:00:00
let day2 = Date(timeIntervalSince1970: 1516089600) // January 16, 2018, 00:00:00
let diff = day2 - day1
print(diff.day!) // 1
But given the following dates, you also get 1:
let day3 = Date(timeIntervalSince1970: 1515916800) // January 14, 2018, 00:00:00
let day4 = Date(timeIntervalSince1970: 1516089600) // January 16, 2018, 00:00:00
let diff2 = day4 - day3
print(diff.day!) // 1
So my first question is wondering why the day difference is the same even though one of the pair is 1 day apart and the other is 2 days apart.
Finally, given the following dates, you get the correct number of 14:
let day5 = Date(timeIntervalSince1970: 1516089600) // January 16, 2018, 00:00:00
let day6 = Date(timeIntervalSince1970: 1517299200) // January 30, 2018, 00:00:00
let diff3 = day6 - day5
print(diff3.day!)
But if you were to go back to static func -(left:right:) and uncomment .weekOfYear and re run the above block of code with day5 and day6 you get 0 days. So my second question is why I'm getting 0 days if I add the .weekOfYear component to the Set.
I included two screenshots of a playground below, first one with .weekOfYear not included and the second one including .weekOfYear:
In the following code
let day3 = Date(timeIntervalSince1970: 1515916800) // January 14, 2018, 00:00:00
let day4 = Date(timeIntervalSince1970: 1516089600) // January 16, 2018, 00:00:00
let diff2 = day4 - day3
print(diff.day!) // 1
you are using diff.day when in fact you should be using diff2.day
As for your second issue, the calendar will return date components by assigning from the maximum to minimum. That is to say that when you add weekOfYear, it assigns a value of 2 to weekOfYear. If you were to print out diff3.weekOfYear, you will get 2 (because the dates come up to be 2 weeks). Since there are no days left behind after the date is converted into weeks, you get 0 days for diff3.day. If you were to use the dates Jan 16th and Jan 31st, you would get a value of 2 for week and 1 for day