Why am I getting and invalid QDateTime object? - qt

My code looks like this
std::string date = "04/05/2015 02:07";
std::string format = "MM/dd/yyyy HH:mm";
QDateTime dateTime = QDateTime::fromString(date.c_str(), format.c_str());
bool isItValid = dateTime.isValid();
This is part of a function I have but I narrowed the problem to specifically that value for date. After executing, isItValid is false. Why is it not a valid date?
However, if I try
bool isItValid = dateTime.date().isValid() && dateTime.time().isValid();
the value is true.
Can anyone point out what's the problem with that date? what am I missing?

The documentatation of isValid() (http://doc.qt.io/qt-5/qdatetime.html#isValid) says:
Returns true if both the date and the time are valid and they are
valid in the current Qt::TimeSpec, otherwise returns false.
If the timeSpec() is Qt::LocalTime or Qt::TimeZone then the date and
time are checked to see if they fall in the Standard Time to Daylight
Time transition hour, i.e. if the transition is at 2am and the clock
goes forward to 3am then the time from 02:00:00 to 02:59:59.999 is
considered to be invalid.
So it seems it's the Qt::TimeSpec you are missing.

Related

How to check if a string denotes a 24 hour valid time format using momentJS?

The code:-
moment(moment("2022-12-12").format("YYYY-MM-DD"), "YYYY-MM-DD", true).isValid()
returns true as 2022-12-12 is a valid date in YYYY-MM-DD format.
Using the same logic, I tried to check if var timeString = "16:00:00" is a valid time or not.
However, the following code:-
moment(moment("16:00:00").format("HH:mm:ss"), "HH:mm:ss", true).isValid()
always gives me false.
What am I doing wrong?
It's always giving true as you are formatting to that particular type first than checking if its valid which is why its always true.
I think you want something like this.
function isTimeFormat(time) {
return moment(time, 'HH:mm:ss', true).isValid();
}

How to create a momentJS object with a specfic time and a specific timezone(other than the default local time zone)?

I will receive an string(with time and date) from the frontend. The string format is this "2021-08-16T23:15:00.000Z". I intend to declare a moment object with the input string, along with a specific timezone(other than the local one).
import moment from "moment";
import "moment-timezone";
// The input string I receive from the frontend.
let strTime = "2021-08-16T23:15:00.000Z";
console.log(strTime); //2021-08-16T23:15:00.000Z
let time = moment.tz(strTime, "YYYY-MM-DDTHH:mm:ss.SSSZ","America/Boise");
console.log(time); // Moment<2021-08-16T17:15:00-06:00>, undesired value
let UTCtime = moment.utc(time);
console.log(UTCtime);
As far as what I understood from this question, console.log(time) should output a moment object of time 23:15:00, but with timezone "America/Boise".
What I intend is time to have the same time i.e "23:15:00.000", with "America/Boise" as timezone.
So that when I later convert that time to UTC, I need to get the right value w.r.t the timezone "America/Boise" and not my local timezone. How can I do this.
I figured out a solution.
const momenttz = require("moment-timezone");
const moment = require("moment");
// The input string I receive from the frontend.
let strTime = "2021-08-16T23:15:00.000Z";
console.log(strTime); //2021-08-16T23:15:00.000Z
let time = moment.utc(strTime);
time.tz("America/Boise", true);
console.log(time.tz());
console.log(time); // Moment<2021-08-16T23:15:00-06:00>, desired value
let UTCtime = moment.utc(time);
console.log(UTCtime); // Moment<2021-08-17T05:15:00Z>
In the above code, at console.log(time),time has the value "23:15:00.000" with required timezone "America/Boise". This makes it possible for you to get the right value , when you later convert it to UTC.
This is made possible by passing an optional second parameter to .tz mutator of moment-timezone as true which changes only the timezone (and its corresponding offset), and does not affect the time value.
time.tz(timezone, true);
A sample example of using this is given in the answer code above.
You can read more about it here in the Moment Timezone Documentation

Moment.js, FullCalendar.js datetime comparisons with timezone offsets

I'm confused.
I have a textbox that is populated with a date and time (string) such as '09/07/2021 10:30'.
I convert this string to a moment like so:
var suggestedDateObj = moment(suggestedDate, 'DD/MM/YYYY HH:mm');
I then want to check if this date and time is in between time slots in a fullcalendar.js event object. I do this like so:
var startDateObj = moment(value.start);
var endDateObj = moment(value.end);
if (suggestedDateObj.isBetween(startDateObj, endDateObj)) {}
However...it isn't working. And it's due to timezone offset (i think).
suggestedDateObj returns a value with a UTC offset of +0100 (British Summer Time)
However my calendar event objects return a date with a UTC offset of +0000. So when i check if '09/07/2021 10:30 +0100' is in between '09/07/2021 10:30 +0000' and '09/07/2021 11:30 +0000' it doesn't work!
I guess my question is really either:
How can I create my suggestedDateObj moment with a timezone offset of zero? OR
How can i tell fullcallendar events that the time it is displaying is actually BST (+0100)? At the moment I don't specify the 'Timezone' parameter.
Thanks.
UPDATE
Hmm....this might work....although it feels a bit clunky:
var tmoment1 = moment(suggestedDate, 'DD/MM/YYYY HH:mm');
//create default date with specific timezone offset of zero
var suggestedDateObj = moment().utcOffset(0);
//set the date and time
suggestedDateObj.set({
day: tmoment1.day(),
month: tmoment1.month(),
year: tmoment1.year(),
hour: tmoment1.hour(),
minute: tmoment1.minute(),
second: 0
});
You can generate suggestedDateObj in utc like that:
var suggestedDateObj = moment.utc(suggestedDate, 'DD/MM/YYYY HH:mm');`
For the .isBetween() I suggest you to use the square bracket like forth parameter, like documentation says.
if (suggestedDateObj.isBetween(startDateObj, endDateObj, undefined, '[]'))
The square brackets indicate that the check must include the dates of the limiter

Issue in converting Timespan variable to 12 hour format

I have a nullable variable Start time
Timespan? st=e.StartTime;//Null-able variable;
I am trying to get time in AM/PM format but I am unable to get it.
DateTime date = Convert.ToDateTime(st.ToString());
String f = String.Format("{0:hh:mm:tt}", date);
Error is:
System.FormatException: String was not recognized as a valid DateTime.
If you were to output the results of st.ToString(), you will find that it doesn't contain any date information, only hours, minutes and seconds.
This isn't a valid format for a DateTime, which generally contain date and time information.
You don't need to convert your TimeSpan to a DateTime to format it, you can just use TimeSpan.ToString():
string f = st.Value.ToString(#"hh\:mm\:tt");
For reference: http://msdn.microsoft.com/en-us/library/ee372287.aspx
Also, note the \ before the :, you must do this if you want to include literal strings in the output, as mentioned at the bottom of that documentation page.
Converting a timespan to a date is not possible, a timespan represents x amount of minutes/hours/whatever and you cannot get an exact date from that alone. If you have a date as a starting point, you can add a timespan and that will give you the new date.
st.ToString() will return "System.Nullable<Timespan>" because that is what a nullable type returns - it does not override the default Object.ToString implementation, so returns the type name.
If you want the string of the actual timespan, then you would need to do st.Value.ToString(), but you should be checking for null first (i.e. st.HasValue == true)
Edit: Also see #Sean's comment about how to output the Timespan without converting to a DateTime first.
Edit: Turns out I was slightly wrong - st.ToString() doesn't return the above. So see Sean's answer.
First convert Timespan to Datetime by adding TimeSpan to a base date of 00:00 hrs. Then on that dateTime derive the 12 hr format.
DateTime.Now.Date.Add(OpenTimeSpan).ToString(#"hh\:mm\:tt")
The Accepted Answer is wrong.
You cannot return AM/PM for a TimeSpan because it is only concerned with the length of Time,
not a Time of Day - hench the name, "TimeSpan".
Convert to a DateTime first before converting to a String:
string sTimeOfDay = new DateTime().Add(st).ToString("hh:mm tt");
Note: If your TimeSpan is nullable, then you will need to add Conditional Logic to Handle Nulls and pass in ts.Value instead of ts:
string sTimeOfDay = (st == null ? null : new DateTime().Add(st.value).ToString("hh:mm tt") );

.NET 2.0 DateTime UTC conversion

Why does the ToUniversalTime function have no effect here;
DateTime dt = new DateTime(2009,3,24,1,0,0,DateTimeKind.Local);
dt = dt.ToUniversalTime(); // convert BST to UTC ?
dt.ToString();
"24/03/2009 01:00:00" ... wrong?
Is the same as..
DateTime dt = new DateTime(2009,3,24,1,0,0,DateTimeKind.Utc);
dt = dt.ToUniversalTime(); // nothing to do, already utc
dt.ToString();
"24/03/2009 01:00:00" ... correct.
I expected there to be an adjustment to the ToString() value of the first example, where by the DateTime specified as Local would result in a corresponding TimeZone calculation upon the call to ToUniversalTime() and the time in the UK should have resulted in
"24/03/2009 00:00:00" as UTC.
However it appears like the specifying of the DateTimeKind in this way renders ToUniversalTime or ToLocalTime unable to make any calculation.
Are you in the UK by any chance? Although we are now in daylight saving time, the date you specify in your code is before this switched over, so local and UTC time in the UK are the same. If you specify April as your month, then you will see a one hour difference.
Cheers David M.
Not had my breakfast. Indeed, when I repeat the test with dates that elapse the BST summer-time threshold, the behaviour is of course correct.
DateTime dt = new DateTime(2009,4,24,1,0,0,DateTimeKind.Local);
dt = dt.ToUniversalTime(); // convert BST to UTC ?
dt.ToString(); // "24/04/2009 00:00:00" ... correct
And to confirm, the ToString() method appears to output based on the Kind property.

Resources