Trying to figure out how to add a century prefix (19 or 20) to a birth date. Does anyone see how to write this in a better way?
public string GetCenturyPrefix(string socSecNo)
{
string prefix = string.Empty;
try
{
var currentDate = DateTime.Now;
var birthDayTemp = socSecNo.Substring(0, 6);
var yy = birthDayTemp.Substring(0, 2);
var mm = birthDayTemp.Substring(2, 2);
var dd = birthDayTemp.Substring(4, 2);
birthDayTemp = yy + "-" + mm + "-" + dd;
var birthDay = Convert.ToDateTime(birthDayTemp);
var totalDays = currentDate - birthDay;
var age = totalDays.TotalDays / 365;
var yearsAfter2000 = Convert.ToInt32(currentDate.Year.ToString().Substring(2, 2));
if (age > yearsAfter2000)
{
prefix = "19";
}
else
{
prefix = "20";
}
}
catch (Exception)
{
}
return prefix;
}
Don't use Substring to parse a string value into a DateTime. .Net has very robust methods created for you to do this conversion.
Here I'm using DateTime.TryParseExact(), which lets me specify the exact format I expect dates values to be provided in. The method returns true or false indicating if the value is in that supplied format. No need to use exceptions to control logic flow.
public string GetCenturyPrefix(string socSecNo)
{
// Check if you're able to parse the incoming value
// in the format "yyMMdd".
if (!DateTime.TryParseExact(socSecNo, "yyMMdd", CultureInfo.InvariantCulture,
DateTimeStyles.None, out DateTime parsedDateTime))
{
// Do something if the input can't be parsed in that format.
// In this example I'm throwing an exception, but you can also
// return an empty string.
throw new Exception("Not valid date format");
}
// Extract only the Year portion as a 4 digit string,
// and return the first 2 characters.
return parsedDateTime.ToString("yyyy").Substring(0, 2);
}
You can do it like (year/100)+1 but put {0:n0} format to your .ToString("{0:n0}") this could be the logic and for the if else it can stay like that. This should be working for any century as I tried on calculator.
Related
Is there a way to convert a yyyy/ddd string to Date in C#?
For example 2019003 is January 3, 2019.
Also to validate if the string is yyyy/ddd format.
Kindly help
You could make a TryParse method like this:
public static bool TryParseSpecialDate(string dateString, out DateTime parsedDate)
{
parsedDate = DateTime.MinValue;
// parse yyyy/DDD into 2 separate capture groups
var match = Regex.Match(dateString ?? string.Empty, #"^(\d{4})/(\d{3})$");
if (!match.Success)
{
return false;
}
// Create a date for yyyy/01/01
var yearDate = new DateTime(int.Parse(match.Groups[1].Value), 1, 1);
var dayOfYear = int.Parse(match.Groups[2].Value);
if (dayOfYear < 1 || dayOfYear > 366)
{
return false;
}
// Add the required number of days
var result = yearDate.AddDays(dayOfYear - 1);
// Check that it's the same year (so that 2019/888 won't work, or 366 in a non leap year)
if (result.Year != yearDate.Year)
{
return false;
}
// Set the date and return it
parsedDate = result;
return true;
}
I've used regex (I didn't need to but it seemed easier, feel free to replace it with string operations instead). This then starts from January in the desired year, and adds the number of days to it.
Usage:
bool success = DateTimeHelpers.TryParseSpecialDate("2019/354", out tmp);
Output will be 2019/12/20
Try it online
You can probably do this:
string julianDate = "2019003";
int year = Convert.ToInt32(julianDate.Substring(0, 4));
int dayOfYear = Convert.ToInt32(julianDate.Substring(4));
DateTime dateTime = new DateTime(year-1, 12, 18, new JulianCalendar());
dateTime = dateTime.AddDays(dayOfYear);
This should return the desired date.
Reference:
I want to covert julian date(YYJJJ format) to any normal date format(MMDDYY) using c#. Is there any defined function for that?
Here's method to achieve that:
public DateTime ParseDateString(string strDt)
{
// validate string, pattern explanation:
// \d - match sigle digit
// ^ - match beginning of a string
// $ - match end of a string
// /? - match zero or one /
if(! Regex.Match(strDt, #"^\d\d\d\d/?\d\d\d$").Success)
throw new ArgumentException("Invalid string");
// get rid of a optional /
strDt = strDt.Replace("/", "");
var days = int.Parse(dt.Substring(4));
var year = int.Parse(dt.Substring(0, 4));
var date = new DateTime(year, 1, 1);
return date.AddDays(days - 1);
}
I have a date coming into my c# program like this: "01/15/2015", and I need to translate that to a string like this: "2015-01-15T00:00:00Z" (i.e., the beginning of that day). I am calling a 3rd party api that expects that format.
Then I need to take the same date and convert it to this: "2015-01-15T23:59:59Z" (i.e., the end of the day given).
Here is what I have, which appears to work based on the limited testing I've done, but I am wondering if this is prone to errors or if there is a better way to accomplish this. I haven't worked with dates in this format before so I thought I'd ask those with more experience. Will T23:59:59Z be the end of the day in the time zone my server is on?
program example:
class Program
{
static void Main(string[] args)
{
Search("01/15/2015");
}
private static void Search(string date)
{
//produce this:
//string startOfDay = "2015-01-15T00:00:00Z";
//string endOfDay = "2015-01-15T23:59:59Z";
DateTime temp1 = DateTime.Parse(date);
string startOfDay = temp1.ToString("yyyy-MM-ddTHH:mm:ssK") + "Z";
DateTime temp2 = DateTime.Parse(date);
string endOfDay = temp2.ToString("yyyy-MM-ddT") + "23:59:59Z";
}
}
Start of day is easy; you can just use .Date.
FYI: Please make sure you check culture.
class Program
{
static void Main(string[] args)
{
DateTime date;
if (DateTime.TryParse("01/15/2015", out date))
{
var startOfDay = date.Date;
Console.WriteLine(startOfDay.ToString("s") + "Z");
var endOfDay = date.ToEndOfDay();
Console.WriteLine(endOfDay.ToString("s") + "Z");
}
Console.ReadLine();
}
}
public static class DateExtensions
{
public static DateTime ToEndOfDay(this DateTime date)
{
return date.Date.AddDays(1).AddTicks(-1);
}
}
private static void Search(string date)
{
DateTime parsedDate;
if (DateTime.TryParseExact(date, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
{
var dateString = parsedDate.ToString("yyyy-MM-dd");
var dateStart = dateString + "T00:00:00Z";
var dateEnd = dateString + "T23:59:59Z";
}
}
This completely ignores time zones or UTC, it simply converts the incoming string to a DateTime representation and then creates the 2 strings which is that date instance formatted and appended the hard coded beginning of day and end of day as a string.
If you want to do it completely in ANSI C here ya go - And this code snip will let you goof around with it at the char level of building the time/date string from scratch. Cheers...
char time_str[22], swap_str[3]; // my time string to build and swap data
void append_tdata(int t_unit, char delimiter); // generic append with dl
main(void)
{
time_t t; // I believe everything here is ANSI C
struct tm *gmt; // and should be very portable
t = time(NULL);
gmt = gmtime(&t); // get zulu time
// start building my string with the year
itoa(gmt->tm_year + 1900, time_str, 10);
append_tdata(gmt->tm_mon, '-'); // YYYY-MM
append_tdata(gmt->tm_mday, '-'); // YYYY-MM-DD
append_tdata(gmt->tm_hour, 'T'); // YYYY-MM-DDTHH
append_tdata(gmt->tm_min, ':'); // YYYY-MM-DDTHH:MM
append_tdata(gmt->tm_sec, ':'); // YYYY-MM-DDTHH:MM:SS
time_str[strlen(time_str) + 1] = 0x0;
time_str[strlen(time_str)] = 'Z'; // YYYY-MM-DDTHH:MM:SSZ
// time_str build is done - do with it as you like
}
//---------------------------------------------------------------
void append_tdata(int t_unit, char delimiter)
{
time_str[strlen(time_str) + 1] = 0x0;
time_str[strlen(time_str)] = delimiter;
if(t_unit < 10) // is the number added to string only one digit?
{ // if so - pad it with a zero
swap_str[0] = '0';
itoa(t_unit, &swap_str[1], 10);
}
else
itoa(t_unit, swap_str, 10); // otherwise just give me the number
strcat(&time_str[strlen(time_str)], swap_str); // add it to my string plz
}
I have a string called value with 1899-12-30 01:30:00
I want to get 01:30 into a seperate string, I have tried to use substring but it keeps giving me an error that the startindex cannot be less than zero, can someone tell me what im doing wrong?
using (OleDbDataAdapter oda = new OleDbDataAdapter("SELECT * FROM [" + sheet1 + "]", excel_con))
{
oda.Fill(dtExcelData);
}
excel_con.Close();
if (dtExcelData.Rows.Count > 0)
{
foreach (DataRow rw in dtExcelData.Rows)
{
//Creates StaffID
rw["StaffID"] = "00" + rw["Host Key of Staff"].ToString();
//Get duration out of DateTime
string Value = rw["Taught Periods Distinct as duration"].ToString();
string Duration = Value.Substring(Value.Length - 10, 5);
rw["Taught Periods Distinct as duration"] = Duration.ToString();
}
}
Debugging it says:
Duration = "01:30" Type String
Value = "30/12/1989 01:30:00" Type String
Value.Length = 19 Type int
rw["Taught periods as distinct as duration"] = "30/12/1989 01:30:00" Type object {string}
First add a break point and see the value of Value, it seems like there is invalid value in your variable.
To extract out 01:30 into a separate string, a better approach would be to use DateTime parsing. Because your string is a valid DateTime value. Use
DateTime parsedDateTime;
string Duration = null;
if (!DateTime.TryParseExact("1899-12-30 01:30:00", //or rw["Taught Periods Distinct as duration"].ToString();
"yyyy-MM-dd HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out parsedDateTime))
{
Console.WriteLine("Invalid date");
}
else
{
Duration = parsedDateTime.ToString("HH:mm", CultureInfo.InvariantCulture);
}
In fact, you want to extract the time (hour + minute) from your date.
For this, I recommend not to do string conversions. Instead, better use a more direct approach by directly using DateTime, like this:
DateTime Value = rw["Taught Periods Distinct as duration"];
rw["Taught Periods Distinct as duration"] = Value.TimeOfDay ;
this works:
string Value = "Taught Periods Distinct as duration".ToString();
string Duration = Value.Substring(Value.Length - 10, 5);
and also:
string Value2 = "1899-12-30 01:30:00";
string Duration2 = Value2.Substring(Value2.Length - 10, 5);
I am using the fullcalendar,
but in IE 10 or 11 the events are not render correct,
I have this:
public static List<DiaryEvent> LoadAllAppointmentsInDateRange(double start, double end)
{
var fromDate = ConvertFromUnixTimestamp(start);
var toDate = ConvertFromUnixTimestamp(end);
using (LolaBikeContext ent = new LolaBikeContext())
{
var rslt = ent.AppointmentDiarys.Where(s => s.DateTimeScheduled >= fromDate && System.Data.Entity.DbFunctions.AddMinutes(s.DateTimeScheduled, s.AppointmentLength) <= toDate);
List<DiaryEvent> result = new List<DiaryEvent>();
foreach (var item in rslt)
{
DiaryEvent rec = new DiaryEvent();
rec.ID = item.Id;
rec.SomeImportantKeyID = item.SomeImportantKey;
rec.StartDateString = item.DateTimeScheduled.ToString("MMMM/dd/yyyy"); // "s" is a preset format that outputs as: "2009-02-27T12:12:22"
rec.StarEvent = item.DateTimeScheduled.ToString("HH:mm"); // ParseExact(start, "HH:mm", CultureInfo.CurrentCulture).ToString(); //item.DateTimeScheduled.ToString("MMMM/dd/yyyy");
rec.EndDateString = item.DateTimeScheduled.AddMinutes(item.AppointmentLength).ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz");// "yyyy-MM-ddTHH:mm:ss.fffZ"); // field AppointmentLength is in minutes
rec.Title = item.Title;// +" - " + item.AppointmentLength.ToString() + " mins";
rec.AppointmentLength = item.AppointmentLength.ToString();
rec.StatusString = Enums.GetName<AppointmentStatus>((AppointmentStatus)item.StatusENUM);
rec.StatusColor = Enums.GetEnumDescription<AppointmentStatus>(rec.StatusString);
string ColorCode = rec.StatusColor.Substring(0, rec.StatusColor.IndexOf(":"));
rec.ClassName = rec.StatusColor.Substring(rec.StatusColor.IndexOf(":") + 1, rec.StatusColor.Length - ColorCode.Length - 1);
rec.StatusColor = ColorCode;
result.Add(rec);
}
return result;
}
}
and especially this line:
rec.EndDateString = item.DateTimeScheduled.AddMinutes(item.AppointmentLength).ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz");// is not rendering correct.
I have read that it has to be in: ISO 8601, so I have looked at this thread:
Given a DateTime object, how do I get an ISO 8601 date in string format?
but that doesnt work. IE is rendering the events not correct
Thank you!!
see the different pictures
The correct image:
I think youare missing the "s" format specifier, which is described as Sortable date/time pattern; conforms to ISO 8601
The EventStart comes in ISO 8601 format and you will need to convert it. you can follow this example to convert current to ISO 8601:
DateTime.UtcNow.ToString ( "s", System.Globalization.CultureInfo.InvariantCulture )
Here's a post about that : Link
As for your code try this instead for your startdatestring and enddatestring:
rec.StartDateString = item.DateTimeScheduled.ToString("s");
rec.EndDateString = item.DateTimeScheduled.AddMinutes(item.AppointmentLength).ToString("s");
I try to popup a msgbox that shows the months and years of the given dates for example
my input is:
7/2012 and 2/2013
and the output should be:
7/2012,8/2012,9/2012,10/2012,11/2012,12/2012,1/2013,2/2013
I wrote:
string datePart1;
string datePart2;
string[] date1 = new string[] { "" };
string[] date2 = new string[] { "" };
private void button1_Click(object sender, EventArgs e)
{
DateTime endDate = new DateTime(2013, 2, 1); // i will be having the date time as a variable from a textbox
DateTime begDate = new DateTime(2012, 7, 1); // i will be having the date time as a variable from a text box
int year, month;
if (endDate.Month - begDate.Month < 0)
{
month = (endDate.Month - begDate.Month) + 12;
endDate = new DateTime(endDate.Year - 1, endDate.Month, endDate.Day);
}
else
month = endDate.Month - begDate.Month;
year = endDate.Year - begDate.Year;
The above code calculates the time difference, but my attempts at outputting haven't worked.
Here's a sample to get you started.
It provides a handy MonthsInRange() method which returns a sequence of all the months in the specified range. You can then format the returned dates using "M\\/yyyy" (see below) to output the required format. (Note: That's not a letter V, it's a backslash followed by a forward slash!)
See Custom Date and Time Format Strings for an explanation of the format string.
using System;
using System.Collections.Generic;
namespace Demo
{
public static class Program
{
static void Main(string[] args)
{
DateTime endDate = new DateTime(2013, 2, 1);
DateTime begDate = new DateTime(2012, 7, 1);
foreach (DateTime date in MonthsInRange(begDate, endDate))
{
Console.WriteLine(date.ToString("M\\/yyyy"));
}
}
public static IEnumerable<DateTime> MonthsInRange(DateTime start, DateTime end)
{
for (DateTime date = start; date <= end; date = date.AddMonths(1))
{
yield return date;
}
}
}
}
Why "M\\/yyyy" and not just "M/yyyy"?
This is because the "/" character in a DateTime format string will be interpreted as the "date separator", not a literal "/". In some locales, this will come out as "." and not "/".
To fix this, we need to escape it with a "\" character. However, we can't just use a single "\" because C# itself will interpret that as an escape character, and will use it to escape the following character. The C# escape sequence for a literal "\" is "\\", which is why we have to put "\\/" and not just "\/".
Alternatively you can turn of escaping of "\" characters by prefixing the string with an # character, like so:
#"M/yyyy"
You can use whichever you prefer.
Since you're not guaranteed to have dates with the same day, you can use this code which creates new dates that only consider the first of the month.
static IEnumerable<string> InclusiveMonths(DateTime start, DateTime end)
{
// copies to ensure the same day.
var startMonth = new DateTime(start.Year, start.Month, 1);
var endMonth = new DateTime(end.Year, end.Month, 1);
for (var current = startMonth; current <= endMonth; current = current.AddMonths(1))
yield return current.ToString("M/yyyy");
}
// usage
foreach (var mmyyyy in InclusiveMonths(begDate, endDate))
{
Console.WriteLine(mmyyyy);
}
var allMonths = string.Join(", ", InclusiveMonths(begDate, endDate));
Look into using the TimeSpan structure, it'll help you achieve your goal a lot faster.
http://msdn.microsoft.com/en-us/library/system.timespan.aspx
You may use
TimeSpan dateDifference = endDate - begDate;
year = dateDifference.Days / 365;
month = dateDifference.Days / 30;
Edit:
I forgot TimeSpan does not feature Year or Month, sorry :(