I essentially have a query that looks like this:
.Where(x=>x.Date < DateTimeOffset.UtcNow)
Now, this has worked as intended so far, but since also adding Arabic into my application, apparently their calendar system uses something called a Hijri calendar?
Anyway, date such as 24/09/2013 looks like 18/05/34 (invented values).
So, the query would end up using the 18/05/1834 date, and thus return no values.
tl;dr I want to be able to query with the non-cultured datetime.
I've tried to google how to use CultureInvariant, but all the solutions showed a .ToString() whereas I need a datetime returned
DateTime and DateTimeOffset don't have any culture. You only use culture info when parsing a string or outputting a string. Internally, they always store their data using the Gregorian calendar. So if you are comparing DateTime or DateTimeOffset values, then it doesn't matter what calendar system is used for display - the comparison will always be done with their Gregorian equivalents.
You had said in your question:
So, the query would end up using the 18/05/1834 date, and thus return no values.
If you are doing things normally, that won't be true. You won't have Hijri formatted dates in your database. Those will all be Gregorian still and the comparison should work as expected. If for some reason you actually have the Hijri values in your data, then somewhere you are passing your values by string, which is getting affected by culture. You shouldn't do that.
Take a look at the sample code in this MSDN entry. It shows clearly that you need to use a calendar object to get numerical equivalents for each part, but there is no way to get back a single non-string value that represents the entire date in a non-Gregorian calendar system.
For example:
DateTime utc = DateTime.UtcNow;
Calendar cal = new HijriCalendar();
int y = cal.GetYear(utc);
int m = cal.GetMonth(utc);
int d = cal.GetDayOfMonth(utc);
Or, as a string:
DateTime utc = DateTime.UtcNow;
var ci = CultureInfo.CreateSpecificCulture("ar-SA");
string s = utc.ToString(ci);
If you want a better way to represent Hijri calendar dates in your code, you might consider using Noda Time instead of the built-in types. It has much better support for alternative calendars. For example:
Instant now = SystemClock.Instance.Now;
CalendarSystem cal = CalendarSystem.GetIslamicCalendar(IslamicLeapYearPattern.Base15, IslamicEpoch.Civil);
ZonedDateTime zdt = now.InZone(DateTimeZone.Utc, cal);
LocalDateTime ldt = zdt.LocalDateTime;
UPDATE
It appears the question was with specific regard to querying in RavenDB, and was discussed here. The problem was tracked down to a culture related bug in RavenDB, and fixed in release 2.5.2715.
Related
Is there any possible way for saving DateTime.Now to ddMMyyyy format without using ToString(). Because whenever I use the string operation the statement is not accepted by entity framework. I need to add DateTime to DB in date format of ddMMyyyy. Is there any way??
It would be silly and counterproductive to store dates as "ddMMyyyy". First of all you'd need a varchar(8), not a DATE or DATETIME.
On top of that, how are you ever going to sort it using ORDER BY, or use BETWEEN queries, or do myDate > someValue / myDate < someValue queries? You can't with a date-string formatted like that.
Also a notation such as "ddMMyyyy" is a User Interface representation of an underlying value. Databases should almost never store User Interface representations, that is a job for the... you guessed it... User Interface.
Best to just forget about it, or else be ready to face the horrible consequences.
Change you SQL Server Database data type from "datetime" to "date" ?
From the article for the DateTime.Parse() method (MSDN Article)
So you can do:
var dateTime = DateTime.Parse("01012001");
Which will give you a DateTime typed object.
If you need to specify which date format you want to use, you would use DateTime.ParseExact (MSDN Article)
Which you would use in a situation like this (Where you are using a British style date format):
string[] formats= { "ddMMyyyy" }
var dateTime = DateTime.ParseExact("01012001", formats, new CultureInfo("en-US"), DateTimeStyles.None);
The format "ddMMyyyy" (or any other format) makes any sense only if we're talking about strings.
If you need only the day, month, and year in the program you can still use the DateTime class.
You simply ignore the other properties like minutes, hours, etc...
DateTime now = DateTime.Now;
Method(now.Day, now.Month, now.Year);
or
DateTime emptyDateTime = new DateTime();
// in this case emptyDateTime values are the following:
emptyDateTime.Year: 1
emptyDateTime.Month: 1
emptyDateTime.Day: 1
emptyDateTime.Hour: 0
emptyDateTime.Minute: 0
emptyDateTime.Second: 0
So this seems like an easy thing to do, but still has me stumped. I want to display a list of strings to my user, based off of a few file's creation dates. So basically, display a list of DateTimes. The challenge is that want to use a custom format (something like 5/6/13 12:01 PM) but I want he date part of that to display differently based on how you have your system displaying the date (ie. a Brit would display that date as 6/5/13).
I thought I could just build two strings (one for date and one for time) and make sure that they date is region-formatted, but there is no default option for 5/6/13 (only 5/6/2013):
http://msdn.microsoft.com/en-us/library/az4se3k1.aspx
Next I hoped maybe the DateTime.ToShortDateString() function would work, but it displays as 5/6/2013 as well.
I know I can use a completely custom format like this: DateTime.ToString("M/d/yy h:mm tt") but I don't want to fix the date with the month before the day.
I suppose if I can' figure anything out then I could just build a custom datetime for America and for Europe and then query the OS for what datetime they are displaying in. But that seems really excessive. Any thoughts?
You could retrieve the current ShortDate format from current culture, change it and use it with ToString()
var currentDate = DateTime.Now;
var shortDateFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
var newShortDateFormat = shortDateFormat.Replace("yyyy", "yy");
Console.WriteLine(currentDate.ToString(shortDateFormat));
Console.WriteLine(currentDate.ToString(newShortDateFormat));
System.Globalization.CultureInfo implements IFormatProvider, so you can provide a CultureInfo object as a parameter to the ToString method.
MSDN seems to have an example of exactly what you want.
I am receiving some data into a variable of type object. In certain cases this data are date values. For that data, I would like to convert this to a string and return it in the same format as it was passed. In some cases, the object could be a datetime, in others a date only or time only values.
As soon as I convert the object to a date or a string, it is obviously given a time of midnight which in my scenario may be a valid time (so I cannot test to see if the time is midnight in which case I could deduce that it would have been a date only date value, nor can I use regex on it as there will always be a time element).
Intellisense shows me it correctly, ie in the format I am wishing to return the value.
Is there an easy way to achieve this (hopefully without using reflection)
Many thx
Simon
Your question is a little unclear but I think you're looking for something like this:
DateTime result;
if (DateTime.TryParse(value, out result))
{
// use result here
}
In the above code value is a string that represents the data coming in. The code will only enter the if block if the string is a valid DateTime. At which point you can do the processing you need on it.
Im not sure i understand the question but i would recommend you to take a look at this conversion example on MSDN, and see the Documentation of the DateTime Structur it contains a lot of Conversion/Formatting Methods i hope it helps.
There are many way to do formatting on the datetime and one of the simple way is fetch the data from the required table in the desired format. Like here you need to display the date and if you your format is dd/MM/yyyy then try this
select Convert(varchar(10),StartDate,103) as StartDateformat from table where filtername=#filtername
use this link to find other format Cast and Convert
From local variable to DateTime Conversion
DateTime todateformat = Convert.ToDateTime(txttodate.Text.Trim());
From DateTime to local variable Conversion in specific format
string startdate = todateformat.ToString("dd/MM/yyyy hh:mm:ss");
My website is hosted on multiple servers at different locations
Everywhere the Culture of the data format is different- we use mm/dd/yyyy format every where but incase some server has the culture set to dd/mm/yyyy then our website generates Datetime exception.
You should be specifying what culture you want to use whenever you convert a string to a date.
The culture you should be using depends on what culture the dates are formatted as. For example, if all dates you are parsing are formatted as Slovak:
String s = "24. 10. 2011";
Then you need to parse the string as though it were in Slovak (Slovakia) (sk-SK) culture:
//Bad:
d = DateTime.Parse(s);
//Good:
d = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("sk-SK")); //Slovak (Slovakia)
If your dates are all in Tajik (Tajikistan Cyrillic), then you need to parse it as tg-Cryl-Tj:
String s = "24.10.11"
DateTime d = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("tg-Cryl-Tj"));
Which leads to the question: what date format are you using? You should not be relying on the locale setting of the server, you should be deciding what format you want.
//Bad
String s = d.ToString();
//Good
String s = d.ToString(CultureInfo.CreateSpecificCulture("si-LK")); //Sinhala (Sri Lanka)
//s = "2011-10-24 12:00:00 පෙ.ව."
i suspect that you prefer to do everything in English. But then you have to decide which variant of English:
en-AU (English Austrailia): 24/10/2011
en-IA (English India): 24-10-2011
en-ZA (English South Africa): 2011/10/24
en-US (English United States): 10/24/2011
i suspect you prefer English (India) (en-IA).
But if you really can't decide what culture to use when converting dates to strings and vice-versa, and the dates are never meant to be shown to a user, then you can use the Invariant Culture:
String s = "10/24/2011" //invariant culture formatted date
d = DateTime.Parse(s, CultureInfo.InvariantCulture); //parse invariant culture date
s = d.ToString(CultureInfo.InvariantCulture); //convert to invariant culture string
Never, ever, store dates internally as strings. Not in the database, not in your app.
If you need to move date values between servers, go binary. Or if you really really have to use strings, use ToString(CultureInfo.InvariantCulture) - or simply serialize the Ticks property.
Also, never pass dates as strings to the database using SQL commands that you build using code. Use SqlParameter for that, or even better, rely on some O/R Mapper, such as Entity Framework or Linq to SQL.
If deployed to a server that's not under your control it's vitally important to make sure your code doesn't have hard-coded dependencies on the culture.
You'll most likely want to search your code for DateTime.Parse or similar. We have a set of extension methods on DateTime that we use instead to force the correct culture.
Never rely on the server's default locale. For your case, this means:
Use prepared statements where you pass the date as (unformatted) date object and not as (formatted) string object. You should never use strings to represent dates in your application anyway, as you cannot perform date-specific functions on them (like adding 1 month, getting the last day of the current week, etc.)
Use SQL functions like to_date and to_char everywhere (exact names depend on your DBMS), if you really need to use string objects in your application
I've looked around a lot and short of writing a horrible chunk of code to manipulate the string, I'd like to ask if anyone knows a nice way of sorting it:
I have a bunch of date strings in cells that I'm pulling out such as:
03/05/2011
27/05/2011
31/05/2011
03/05/2011
09/05/2011
31/05/2011
etc.
While I'm reading any entires where the day can be construed as a month - i.e. entries 1, 4 and 5 above - it gets put in as a DateTime with the day and month swapped.
For example, 03/05/2011 gets read in as a DateTime "05/03/2011 00:00:00"
The others are all read and nicely provide me with a simple string of "27/05/2011".
I'm getting this info from Excel, using
((Excel.Range)worksheet.Cells[rowCount, 3]).Value.ToString()
If I try Value2 as with my other lines, it reads those odd dates as things like "40607" but again, will read the other dates normally.
If you use the DateTime.ParseExact function to convert a string to a DateTime object, you can specify the specific format used by your dates (which looks like "day/month/year") without having to do any string manipulation whatsoever.
Example:
var dateString = "03/05/2011";
var format = "dd/MM/yyyy";
var date = DateTime.ParseExact(dateString, format, CultureInfo.InvariantCulture);
More information on custom Date and Time format strings can be found here.
EDIT: Try using the DateTime.FromOADate method to convert the value returned by the Range.Value2 property to a DateTime object, e.g. something like this:
var dateTime = DateTime.FromOADate(((Excel.Range)worksheet.Cells[rowCount, 3]).Value2);
DateTime.ParseExact Method converts the specified string representation of a date and time to its DateTime equivalent using the specified format and culture-specific format information.
The format of the string representation must match the specified format exactly.
String dateString = "15/06/2008";
String format = "dd/MM/yyyy";
DateTime result =
DateTime.ParseExact(dateString, format, CultureInfo.InvariantCulture);
That sounds like a localization problem. Try setting your locale implicititly. For example in WPF application it's something like:
System.Threading.Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo("en-US");
I have a bunch of date strings in cells that I'm pulling out such as:
No, you don't. You have a mix of strings that look like dates and dates that look like strings. This is an Excel issue, not a C# issue.
Not sure if you are creating the spreadsheet, or if you are getting it from somewhere else. But it the problem is that Excel attempt to parse text as it is entered in the cell. In this case, it is making some wrong decisions about the dates it finds.
If you enter a date like "03/05/2011", Excel will (incorrectly) parse it as March 5th, 2011, and store that as a numeric date code (40607). It then applies a date formatting to the cell (it uses m/d/yyyy on my machine).
If you enter a date like "31/05/2011", Excel can't parse it as a date, and it stores it as text.
To prove this, select the cells and go to Edit > Clear > Formats. All the "bad dates" will just show as numbers, all the rest will stay looking like dates.
You have a few choices:
Fix the data before its entered into Excel (prepend everything with a ' so its all entered as text, or make sure to create the spreadsheet on a machine that has the right date settings.)
Don't use the .Value.ToString() from Excel, just use .Text. This will ignore the bad parsing that Excel did, and should give you a consistent text value (from both types) that you can ParseExact with C#, per the other answers.
(2) is a lot easier, and if the spreadsheets already exist, may be your only choice.
The problem is because your Dates are being read as american culture or similar.
If you use the following you can specify the format you expect your dates to be in:use
DateTime result;
if(DateTime.TryParseExact("dd/MM/yyyy", out result))
{
// Got an English date
}