I have a JS function that generates today date:
function GetDate(date) {
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0');
var yyyy = today.getFullYear();
today = dd + '/' + mm + '/' + yyyy;
alert(today);
return today; // 13/03/2021
}
This function returns 13/03/2021
I pass it on to Server Side Code and do this :
DateTime dateToday = DateTime.ParseExact(cdate, "dd/MM/yyyy", CultureInfo.GetCultureInfo("en-AU"));
emailCopy = emailCopy.Replace("{date}", dateToday.ToString("dd MMMM yyyy"));
However here it puts the date as 12 March 2021
Why is it doing that? The date going in is clearly 13/03/2021. Also in next line I pass this date to be added to SQL Server Table:
dateToday.ToString("yyyy-MM-dd")
And the date added to the database is also correct : 2021-03-13.
When you create a new DateTime object, but only set the date part of it, this sets the time to 00:00:00 (midnight). This is in GMT. So when you format the date it takes the date you set at midnight, and converts it to your time zone, which is actually the day before.
You can fix this by doing this "kludge":
var now = DateTime.Now;
var adjusted = new DateTime(
dateToday.Year, dateToday.Month, dateToday.Day, now.Hour, now.Minute, now.Second);
var final = adjusted.ToString("dd MMMM yyyy");
There may be a better way to do this, though.
ETA
You should consider using JavaScript's Date.toISOString() instead of just sending the date. Then in C#, use Convert.ToDateTime() to parse it. That uses UTC and you are guaranteed to get the exact time that the client machine generated the date.
Related
TL:DR: I have the following input string:
Thu Mar 09 2017 18:00:00 GMT+0100
And I am trying to convert it to a DateTime object using the format:
"ddd MMM dd yyyy HH:mm:ss"
This obviously doesn't work as I am ignoring the GMT+0100 part. How can I include this?
I don't manage to parse and convert following input to a correct UTC DateTime object:
input string selectedDate:
1,Thu Mar 09 2017 18:00:00 GMT+0100 (W. Europe Standard Time)
function:
var splittedValues = selectedDate.Split(',');
var selectDayOfWeek = (DayOfWeek)int.Parse(splittedValues[0]);
var selectedTime = DateTime.ParseExact(splittedValues[1].Substring(0, 24),
"ddd MMM d yyyy HH:mm:ss",
CultureInfo.InvariantCulture);
DateTime today = new DateTime(DateTime.Today.Ticks, DateTimeKind.Unspecified);
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilNextTargetDay = ((int)selectDayOfWeek - (int)today.DayOfWeek + 7) % 7;
DateTime nextTargetDay = today.AddDays(daysUntilNextTargetDay).AddHours(selectedTime.Hour).AddMinutes(selectedTime.Minute);
return nextTargetDay.ToUniversalTime();
results time portion is always 18:00:00
should be 17:00 as the input was actually GMT +01
Whats the issue here?
update:
as others pointed out there were mistakes so I updated my code to:
var splittedValues = selectedDate.Split(',');
var selectDayOfWeek = (DayOfWeek)int.Parse(splittedValues[0]);
var selectedTime = DateTime.ParseExact(splittedValues[1].Substring(0, 33),
"ddd MMM dd yyyy HH:mm:ss",
CultureInfo.InvariantCulture).ToUniversalTime();
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilNextTargetDay = ((int)selectDayOfWeek - (int)DateTime.Today.DayOfWeek + 7) % 7;
DateTime nextTargetDay = DateTime.Today.AddDays(daysUntilNextTargetDay).AddHours(selectedTime.Hour).AddMinutes(selectedTime.Minute);
return nextTargetDay;
but now the parsing fails as the substring does not match "ddd MMM dd yyyy HH:mm:ss"
how does the GMT+0100 has to be included here?
Use TimeZoneInfo when converting between specific time zones:
TimeZoneInfo westInfo =
TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
DateTime westTime = DateTime.Parse("2012.12.04T08:35:00");
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(westTime, westInfo);
To address your confusion:
DateTime.Parse as used here makes no assumptions about the timezone of the given value. IT stores it with a DateTimeKind of Unspecified.
TimeZoneInfo.ConvertTimeToUtc as used here expects an Unspecified datetime, reads it as if it is in the explicitly specified time zone, and converts it to UTC.
Changing your code to this (adding ToUniversalTime() before adding days) fixed it for me.
DateTime nextTargetDay = today.ToUniversalTime().AddDays(daysUntilNextTargetDay).AddHours(selectedTime.Hour).AddMinutes(selectedTime.Minute);
Then of course you can just return nextTargetDay; at the end.
Looking into MSDN I can spot an initial problem with your code. This is that you are using d where you should be using dd as the day is 09 not 9.
d: The day of the month, from 1 through 31.
dd: The day of the month, from 01 through 31.
Secondly, the reason the +1 is "ignored" is that you exclude it in the substring, i.e.
splittedValues[1].Substring(0, 24) == "Thu Mar 09 2017 18:00:00";
So essentially you need to include that part of the string with the correct format specifier (I'm not sure which one). Or interrogate it yourself and subtract one hour off of the result as needed.
Side note: The following code is weird (in my opinion, there may be a reason for it):
DateTime today = new DateTime(DateTime.Today.Ticks, DateTimeKind.Unspecified);
You can either use DateTime.Today or DateTime.Now.Date.
As mentioned in the answer by #calypso you can use the TimeZoneInfo class. Their answer goes over a general approach of how to use it. But for your particular example you can do (code is untested but looks like it should work):
var selectedTime = DateTime.ParseExact(splittedValues[1].Substring(0, 24), "ddd MMM dd yyyy HH:mm:ss", CultureInfo.InvariantCulture);
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(splittedValues[1].Substring(splittedValues[1].IndexOf("(") + 1).TrimEnd(")"));
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(selectedTime, timeZoneInfo);
I have this as my syntax which when I step through the code it provides the accurate date, however when I use it to create the Directory it gives me an inaccurate date (date used to create the folder is 33.22.15_Created Programmatically"
DateTime upcomingMonday = DateTime.Now;
while (upcomingMonday.DayOfWeek != DayOfWeek.Monday)
{
upcomingMonday = upcomingMonday.AddDays(1);
}
Directory.CreateDirectory(SaveLocation + upcomingMonday.ToString("mm.dd.yy") + "_Created Programattically\\");
mm is for minutes. Use:
upcomingMonday.ToString("MM.dd.yy")
MM gets the month, padded with a 0 if necessary (January => 01, December => 12).
See Custom Date and Time Format Strings from MSDN.
I have the following text that I am trying to parse into a date, but I can't seem to get the time zone correct.
Ideas?
Fri May 29 2015 00:00:00 GMT-0700 (Pacific Daylight Time)
(I can't change the date structure)
Try this:
string str = "Fri May 29 2015 00:00:00 GMT-0700 (Pacific Daylight Time)";
DateTime dt = new DateTime();
bool b = DateTime.TryParseExact(str.Substring(0,33), "ddd MMMM dd yyyy hh:mm:ss 'GMT'zzz", null, DateTimeStyles.None, out dt);
This makes the assumption that the description of the time zone is irrelevant since the offset from GMT is given. Therefore, parsing the substring of the original date string only upto the timezone offset part should be sufficient.
Demo
there is a shortcut way that I sometimes use.
first split the string based on space like:
var dateString = 'Fri May 29 2015 00:00:00 GMT-0700 (Pacific Daylight Time)';
var dateArray = stdateString.Split(' ');
second we need time. for that
var timeString = dateArray[4];
var timeArray = timeString.Split(':');
third for timezone
var timezoneString = dateArray[5];
var timezoneSignPart = timezoneString.Substring(3,1)
var timezoneHourPart = timezoneString.Substring(4,2)
var timezoneMinPart = timezoneString.Substring(6,2)
After that you may use to construct the date however you want to like
This is very personal way for me when I don't have much time to investigate what is the problem ob the coming date strings.
I am working on passing a formatted datetime variable to SQL Server. I need to concatenate the date with the time, as they come from 2 different controls. The code seems to work okay and the two strings, once put together, are parsed as DateTime.
The problem is that when it goes up to SQL Server, the time part is lost and the column displays yyyy-mm-dd hh:mm:ss.fff as 2012-09-03 00:00:00.000 as opposed to 2012-09-03-12 1:23:45:678 (for example).
Here's my code, for testing I have replaced the time with a hard-coded variable, and objInfo.SemesterEnrollStart is a DateTime variable. Also, the control dpEnrollStart is a DatePicker.
DateTime semDate = Convert.ToDateTime(dpEnrollStart.SelectedDate);
string semTime = "12:34";
DateTime dtp = DateTime.ParseExact(semDate.ToShortDateString() + " " + semTime, "MM/dd/yyyy hh:mm", null);
objInfo.SemesterEnrollStart = dtp;
Thanks so much!
EDIT:
So, here's the c# that I am using to call the stored procedure:
objInfo.SemesterQuarter = ddl_SemQuarter.SelectedValue;
objInfo.SemesterYear = ddl_SemYear.SelectedValue;
objInfo.SemesterStart = Convert.ToDateTime(dpSemStart.SelectedDate);
objInfo.SemesterEnd = Convert.ToDateTime(dpSemEnd.SelectedDate);
DateTime semDate = Convert.ToDateTime(dpEnrollStart.SelectedDate);
string semTime = "12:34:00.000";
objInfo.SemesterEnrollStart = DateTime.ParseExact(semDate.ToShortDateString() + " " + semTime, "MM/dd/yyyy HH:mm:ss.fff", null);
objInfo.SemesterEnrollEnd = Convert.ToDateTime(dpEnrollEnd.SelectedDate);
objInfo.PriorityRegDate = Convert.ToDateTime(dpPriRegDate.SelectedDate);
objInfo.AgeCutoffDate = Convert.ToDateTime(dpAgeCutoffDate.SelectedDate);
lblTSMessage.Text = objInfo.SemesterEnrollStart.ToString();
objManager.AddNewSemester(objInfo);
The problem is in the format you are using in ParseExact:
MM/dd/yyyy hh:mm
Therefore, you are purposely discarding the seconds and milliseconds part.
Instead, you need to parse your date with: yyyy-MM-dd HH:mm:ss.fff but then you will need to capture seconds (ss) and milliseconds(fff) in the semTime variable or the ParseExact method will crap out.
One Example:
string s = "01/01/2012 11:23";
//FAILS because there's not ss and fff part
DateTime dtp = DateTime.ParseExact(s, "MM/dd/yyyy hh:mm:ss.fff", null);
string s = "01/01/2012 11:23:12.678";
//Works because there's a ss and fff part
DateTime dtp = DateTime.ParseExact(s, "MM/dd/yyyy hh:mm:ss.fff", null);
I have a date string, returned from a ExtJS datetime picker, which looks like this:
Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)
From this I would need to have it in this format : YYYY-mm-dd, using C# or JavaScript.
How could I do this? I've tried using DateTime.Parse and it cannot be parsed.
Any idea?
You don't seem to care about the time and timezone information so you can in fact use DateTime.ParseExact to parse the date. Assuming that the day of month part may be just a single digit (e.g. 2012-04-01 is Sun Apr 1 2012) the pattern you need to use is ddd MMM d yyyy.
The "hardest" part is really chopping of the time and timezone part. If the day of month is a single digit you have to take of substring of length 14; otherwise of length 15. Here is a way to get the index of the 4th space character in a string:
var str = "Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)";
var index = -1;
for (var i = 0; i < 4; i += 1)
index = str.IndexOf(' ', index + 1);
You can then parse the date into a DateTime:
var date = DateTime
.ParseExact(str.Substring(0, index), "ddd MMM d yyyy", CultureInfo.InvariantCulture);
This can be formatted back into a string using whatever format and culture you need.
In .NET, where you have a string representation of a date that has a guaranteed format, you can use DateTime.ParseExact to parse it:
var input = "Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)"
.Substring(0, 15);
var format = "ddd MMM dd YYYY";
var date = DateTime.ParseExact(input, format, CultureInfo.InvariantCulture);
// Now date is a DateTime holding the date
var output = date.ToString("yyyy-MM-dd");
// Now output is 2012-04-25
May be this can help you Click
try this using Javascript.
var d = new Date('Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)');
var curr_day = d.getDate();
var curr_month = ('0'+(d.getMonth()+1)).slice(-2)
var curr_year = d.getFullYear();
var new_date = curr_year+"-"+curr_month+"-"+curr_day;
In JavaScript
new Date("Wed Apr 25 2012 00:00:00 GMT+0300 (GTB Daylight Time)")
Will give you a date object. You can then format it to your date format (or preferably ISO8601, or milliseconds from the epoc using .getTime()) by picking out the (UTC) year, month and day