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 :(
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
}
Below is my code. I am only getting the difference between two dates, but I want the name of that month which comes between the from and to dates.
public static int GetMonthsBetween(DateTime from, DateTime to)
{
if (from > to) return GetMonthsBetween(to, from);
var monthDiff = Math.Abs((to.Year * 12 + (to.Month - 1)) - (from.Year * 12 + (from.Month - 1)));
if (from.AddMonths(monthDiff) > to || to.Day < from.Day)
{
return monthDiff - 1;
}
else
{
return monthDiff;
}
}
Based on your code you could substract the month difference from the "to" DateTime to get DateTime difference from your input.
public static List<DateTime> GetMonthsBetween(DateTime from, DateTime to)
{
if (from > to) return GetMonthsBetween(to, from);
var monthDiff = Math.Abs((to.Year * 12 + (to.Month - 1)) - (from.Year * 12 + (from.Month - 1)));
if (from.AddMonths(monthDiff) > to || to.Day < from.Day)
{
monthDiff -= 1;
}
List<DateTime> results = new List<DateTime>();
for (int i = monthDiff; i >= 1; i--)
{
results.Add(to.AddMonths(-i));
}
return results;
}
To get the name of the month just format the DateTime to "MMM".
var dts = GetMonthsBetween(DateTime.Today, DateTime.Today.AddMonths(5));
foreach (var dateTime in dts)
{
Console.WriteLine(dateTime.ToString("MMM"));
}
If you want the names of all months between two dates, use something like this:
var d1 = new DateTime(2015,6,1);
var d2 = new DateTime(2015,9,1);
var monthlist = new List<string>();
string format = d1.Year == d2.Year ? "MMMM" : "MMMM yyyy";
for (var d = d1; d <= d2; d = d.AddMonths(1))
{
monthlist.Add(d.ToString(format));
}
The full list is now in monthlist - you will want to return that from your method.
Assuming you're using Java and JodaTime there are several flaws in your code.
You cant use from > to to evaluate if a date is after an other. Use from.isAfter(to) instead.
JodaTime already supplies a method to calculate the amount of whole months between two given Dates Months.monthsBetween(start,end).
With the calculated month difference you can instantiate a new DateTime object that holds a date in your desired month and output its name via yourNewDateTimeObject.month().getAsText().
edit: Just found out you're using C# so ignore my text above this. Below here I will try to answer your question in C#.
Why dont you just subtract the from from the to date and obtain your difference?
The resulting TimeSpan can be used to determine the amount of whole months between your two given dates.
To obtain the resulting month name you could use yourDateTime.ToString("MMMM");
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'm trying to learn how to schedule pictures depending on what time a user has selected.
Here is code with questions:
private void startjob()
{
string theDate = DateTimePicker1.Value.ToString();
DateTime dt = Convert.ToDateTime(date);
{
DateTime start = new DateTime(2009, 12, 9, 10, 0, 0); //How Do I make this to read the string that is converted from DateTimePicker instead of this?
DateTime end = new DateTime(2009, 12, 10, 12, 0, 0); //How Do I make this to read the string that is converted from DateTimePicker instead of this?
DateTime now = DateTime.Now;
if ((now > start) && (now < end))
{
//match found
}
}
}
DateTimePicker.Value returns the DateTime object. You're trying to convert to and from a string type unnecessarily.
DateTime start = DateTimePickerStart.Value;
DateTime end = DateTimePickerEnd.Value;
Supposing your controls are named as DateTimePicker1 and DateTimePicker2:
private void startjob()
{
DateTime start = DateTimePicker1.Value;
DateTime end = DateTimePicker2.Value;
DateTime now = DateTime.Now;
if ((now > start) && (now < end))
{
//match found
}
}
DateTimePicker.Value property is a DateTime object itself, hence your code can be simplified, no need to convert to string.