In database I have a string that represent a date time that format is YY.MM (YY it means Year and MM is Month. for example 21.03 = 2021.03)
How can I map this special format(yy.mm) to this format(mm/yyyy) by using data annotation or another way ?
Try Parse date and then format back to the string:
using System.Globalization;
...
string source = "21.03";
// 03.2021
string result = DateTime
.ParseExact(source, "yy'.'MM", CultureInfo.InvariantCulture)
.ToString("MM'.'yyyy");
However, we have an ambiguity here: "03.50" can be either "March 1950" or "March 2050". The default policy is 00..29 to 2000..2029 and 30..99 to 1930..1999 if you want to change this policy you can create and use your own culture:
CultureInfo myCulture = CultureInfo.InvariantCulture.Clone() as CultureInfo;
// Everything to 20.., never 19..
myCulture.Calendar.TwoDigitYearMax = 2099;
string source = "99.03";
// 03.2099
string result = DateTime.ParseExact(source, "yy'.'MM", myCulture).ToString("MM'.'yyyy");
Or even
CultureInfo myCulture = CultureInfo.CurrentCulture.Clone() as CultureInfo;
// Everything to 20.., never 19..
myCulture.Calendar.TwoDigitYearMax = 2099;
// Current culture as usual, except 2 digit year policy
CultureInfo.CurrentCulture = myCulture;
...
string source = "99.03";
// 03.2099
string result = DateTime.ParseExact(source, "yy'.'MM", null).ToString("MM'.'yyyy");
You can do it like this using the string split function:
string dateIn = "11.10";
string month = dateIn.Split('.')[1]; //split the String at the point and save it
string year = dateIn.Split('.')[0];
string dateOut = $"{month}/20{year}"; //build a new string
//this will fix the 1900/2000 issue more or less as all dates in the furutre would be send back to the past you can adapt this to your need:
if( DateTime.Now.Year < Convert.ToInt32($"20{year}"))
{
dateOut = $"{month}/19{year}";
}
//dateOut is "10/2011"
Related
I trying to parse a string like 4212021 where 4 is the month, 21 is the day, and 2021 is the year, into a DateTime object. I've tried using the following code but for some reason I am getting 'String '4212021' was not recognized as a valid DateTime.':
string datetimestring = "4122021";
var date = DateTime.ParseExact(datetimestring, "Mddyyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal);
All help is appreciated. Thanks.
This doesn't work without date separators. So you could add them:
string format = "Mddyyyy";
CultureInfo culture = CultureInfo.InvariantCulture;
string separator = culture.DateTimeFormat.DateSeparator;
if(datetimestring.Length >= format.Length)
{
int firstIndex = datetimestring.Length % 2 == 0 ? 2 : 1;
datetimestring = datetimestring.Insert(firstIndex, separator);
datetimestring = datetimestring.Insert(firstIndex + 2 + separator.Length, separator);
}
DateTime date = DateTime.Parse(datetimestring, culture, DateTimeStyles.None);
This works also if the month has two digits like in "12122021".
Another, maybe simpler way was to use ParseExact with "Mddyyyy HHmmss" and append zero time:
datetimestring = datetimestring + " 000000"; // check first length ofc
DateTime date = DateTime.ParseExact(datetimestring, "Mddyyyy HHmmss", culture, DateTimeStyles.None);
It's just the "M" modificator that does not work if you use it without separators AND with variable length. If you ensure leading zeros, it should work. ("04" instead of "4")
string datetimestring = 4122021.ToString("D8");
var date = DateTime.ParseExact(datetimestring, "Mddyyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal);
Since your day is always 2 digits (dd) you can just append a 0 to the start of the string when the month only has 1 digit, and use the MM for month:
string datetimestring = "4122021";
var date = DateTime.ParseExact(datetimestring.PadLeft(8,'0'), "MMddyyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal);
I am imagining you have a special reason for not changing the input. You can try this way, it will work.
string datetimestring = "4122021";
var date = DateTime.ParseExact(datetimestring.Length < 8 ? $"0{datetimestring}" : datetimestring, "Mddyyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal);
See if it is appropriate for your context?
I have a string ("CompletionDate") which contains the value "2/28/2017 5:24:00 PM"
Now I have 2 variables (EDate and ETime). I want to assign the Date to EDate (i.e 2/28/2017) and Time to ETime (i.e. 5:24:00 PM).
How can I split the Date and Time from a single string.
Kindly Help.
My approach right now is like :
string CompletionDate = string.Empty;
string ProjectEDate = string.Empty;
string ProjectETime = string.Empty;
CompletionDate = "2017-03-29 12:58:00";
DateTime dt = DateTime.ParseExact(CompletionDate, "yyyy-MM-dd", CultureInfo.CreateSpecificCulture("en-us"));
DateTime dt1 = DateTime.ParseExact(CompletionDate, "HH:mm:ss", CultureInfo.CreateSpecificCulture("en-us"));
var ProjectEDate = dt.ToString();
var ProjectETime = dt1.ToString();
But its throwing exception that string is not in correct format. Kindly help
#Chris pointed one of your problems, but you have one more. You are passing full date time string and trying to treat it as date or time only, which is not true. Instead I suggest you to parse DateTime object with both date and time, and then take whatever you need from parsed object:
CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-us");
DateTime dt = DateTime.ParseExact(CompletionDate, "yyyy-MM-dd HH:mm:ss", enUS);
var ProjectEDate = dt.Date.ToString();
var ProjectETime = dt.TimeOfDay.ToString();
You need to specify the full format as same as the input string to parse method.
DateTime dt = DateTime.ParseExact(CompletionDate, "yyyy-MM-dd HH:mm:ss", System.Globalization.CultureInfo.CreateSpecificCulture("en-us"));
To get results you can use below methods available by default in DateTime.
dt.ToShortTimeString()
"12:58 PM"
dt.ToLongTimeString()
"12:58:00 PM"
dt.ToLongDateString()
"Wednesday, March 29, 2017"
dt.ToShortDateString()
"3/29/2017"
Or you can specify the format to ToString method.
dt.ToString("yyyy-MM-dd")
"2017-03-29"
dt.ToString("HH:mm:ss")
"12:58:00"
DateTime.ParseExact(CompletionDate, "yyy-MM-dd", ...
You are missing 4th 'y' in date format string:
"yyyy-MM-dd"
^
here
and:
String was not recognized as a valid DateTime " format dd/MM/yyyy"
Why do you parse into DateTime and then convert to a string using ToString again? CouldnĀ“t you just simply use String.Split when all you want is to split the time from the day and you know the exact format?
var CompletionDate = "2017-03-29 12:58:00";
var tmp = CompletionDate.Split(' ');
var ProjectEDate = tmp[0];
var ProjectETime = tmp[1];
When using CultureInfo.CurrentCulture.DateTimeFormat to get local date formats, is there a built in way to get only the day and month portion of the date returned by the local ShortTimePattern? e.g. dd/MM
Basically, in my razor view, I am doing something like this:
#someObject.Date.ToString("dd/MM")
But now need to make it work with the current culture so am hoping to find a way to provide a dynamic format mask based on the current culture. Imagine something like:
#someObject.Date.ToString(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePatternNoYear)
Setting the month and day pattern for each culture is bad news. The DRY principle in this case says to leverage each culture's date-time format, not repeat (and possibly contradict) it with a custom MonthDayPattern.
Instead leverage the Short Date ("d") format specifier to get the month and day in the proper order and properly separated for the culture in question, and then whack the year (and its separator).
var de = CultureInfo.CreateSpecificCulture("de-DE").DateTimeFormat;
var uk = CultureInfo.CreateSpecificCulture("en-GB").DateTimeFormat;
var us = CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat;
var now = DateTime.Now;
var yearNow = now.Year.ToString(CultureInfo.InvariantCulture);
const string yearPattern = "(^{0}{1}|{1}{0}$)"; // {0} = year, {1} = date separator
var deDate = now.ToString("d", de);
var deYearlessDate =
Regex.Replace(
deDate,
String.Format(yearPattern, yearNow, de.DateSeparator),
"");
// or a double String.Replace instead of a Regex.Replace
//var deYearlessDate =
// deDate.Replace(de.DateSeparator + yearNow, "").Replace(yearNow + de.DateSeparator, "");
var ukDate = now.ToString("d", uk);
var ukYearlessDate =
Regex.Replace(
ukDate,
String.Format(yearPattern, yearNow, uk.DateSeparator),
"");
// or a double String.Replace instead of a Regex.Replace
//var ukYearlessDate =
// ukDate.Replace(uk.DateSeparator + yearNow, "").Replace(yearNow + uk.DateSeparator, "");
var usDate = now.ToString("d", us);
var usYearlessDate =
Regex.Replace(
usDate,
String.Format(yearPattern, yearNow, us.DateSeparator),
"");
// or a double String.Replace instead of a Regex.Replace
//var usYearlessDate =
// usDate.Replace(us.DateSeparator + nowYear, "").Replace(nowYear + us.DateSeparator, "");
Console.WriteLine(deYearlessDate); // 02.04
Console.WriteLine(ukYearlessDate); // 02/04
Console.WriteLine(usYearlessDate); // 4/2
The solution is to find your current culture and update the DateTimeFormat.MonthDayPattern.
Custom culture aware date format in .NET said that ShortDatePattern ("d") was unreliable and suggested the following method:
private static string FindMonthDayOnly(System.Globalization.CultureInfo ci)
{
string shortPattern = ci.DateTimeFormat.ShortDatePattern;
while(shortPattern[0] != 'd' && shortPattern[0] != 'M')
{
shortPattern = shortPattern.Substring(1);
if(shortPattern.Length == 0)
return ci.DateTimeFormat.ShortDatePattern;
}
while(shortPattern[shortPattern.Length - 1] != 'd' && shortPattern[shortPattern.Length - 1] != 'M')
{
shortPattern = shortPattern.Substring(0, shortPattern.Length - 1);
if(shortPattern.Length == 0)
return ci.DateTimeFormat.ShortDatePattern;
}
return shortPattern;
}
Then all you have to do is find somewhere convenient to run something like this (think carefully about background threads etc as this will only work with the current thread):
var culture = new CultureInfo(CultureInfo.CurrentCulture.IetfLanguageTag);
var newMonthDayString = FindMonthDayOnly(culture);
culture.DateTimeFormat.MonthDayPattern = newMonthDayString;
Thread.CurrentThread.CurrentCulture = culture;
Thanks for everyone's input. This seems to be working but please comment if you see any obvious issues with the solution.
I have created an Extension method to display only Month and day depending of the CultureInfo, hope it helps:
/// <summary>
/// Return a date formatted MonthDay depending of the current application cutlure
/// </summary>
/// <param name="datetime">The datetime to parse</param>
/// <returns>A Month day string representation</returns>
public static string ToMonthDay(this DateTime datetime)
{
// Get the current culture of the application
var culture = new CultureInfo(Thread.CurrentThread.CurrentCulture.Name);
// Get the format depending of the culture of the application
var output = culture.DateTimeFormat.ShortDatePattern;
// Remove the Year from from the date format
var format = output.Replace("Y", "").Replace("y", "");
// Remove any character before or after in the text string which is not a number
Regex rgx = new Regex("^[^a-zA-Z0-9]|[^a-zA-Z0-9]$");
format = rgx.Replace(format, "");
return datetime.ToString(format);
}
And the usage:
DateTime dateToDisplay = new DateTime(2009, 01, 31);
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
Console.WriteLine(dateToDisplay.ToMonthDay());
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Console.WriteLine(dateToDisplay.ToMonthDay());
I have a date returned from database which includes even the time. i want to remove the time part of the string and send only the date. my code is as given below
DateTime Var = new DateTime();
Var = Convert.ToDateTime(Dset.Tables[1].Rows[i]["Date"]);
Var = Var.ToShortDateString();
DateTime Var = Convert.ToDateTime(Dset.Tables[1].Rows[i]["Date"]).Date; //only date part
string date = Var.ToShortDateString();
it will store only date in DateTime object
Var = Var.Date;
time will be 00:00:00
or you can store it as string:
var dateString = Var.ToShortDateString();
you can custom your date string format by using DateTime.ToSting("your format") method.
then the code will be like this.
DateTime Var = new DateTime();
Var = Convert.ToDateTime(Dset.Tables[1].Rows[i]["Date"]);
Var = Var.ToString("yyyy-MM-dd");
you can also use SubString() method to gain the date part of the datetime string.
In my C# Data Access Layer...I am retrieving a dataset from Excel ...and there is a decimal excel field which returns date in the format : 20090701. I need this to be converted to C# DateTime. What is the best way to do it?
DateTime.ParseExact( value.ToString(), "yyyymmdd" );
The ParseExact method allows you to specify the format string for the date/time you are converting. In your case: a four digit year, then two digit month, then two digit day of month.
I would do something like this if you want to implement it application wide.
System.Globalization.CultureInfo cultureInfo =
new System.Globalization.CultureInfo("en-CA");
// Defining various date and time formats.
dateTimeInfo.LongDatePattern = "yyyyMMdd";
dateTimeInfo.ShortDatePattern = "yyyyMMdd";
dateTimeInfo.FullDateTimePattern = "yyyyMMdd";
// Setting application wide date time format.
cultureInfo.DateTimeFormat = dateTimeInfo;
// Assigning our custom Culture to the application.
//Application.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
DateTime.Parse(excelDate);
And a less intuitive answer for good measure.
var a = 20090701m;
var b = a / 10000;
var year = (int)b;
var c = (b - year) * 100;
var month = (int)c;
var day = (int)((c - month) * 100);
var dt = new DateTime(year, month, day);