• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 45
  • Last Modified:

How to calculate a date string value back to a specific Month

How can I calculate a date back in time / month f.ex (01.05).

if my date string is 01.01.2010 and i want to calculate total months back to 01.05.2009.
Don't matter what type of date string i have, all dates have to be calculated back to 01.05

I have a list of startdate, where I need to loop all dates and calculate months back to 01.05.

How can I do this?
0
Adnan
Asked:
Adnan
  • 5
  • 5
  • 3
  • +1
1 Solution
 
Chris StanyonCommented:
This can get a little tricky because it depends on how you define a 'month'. Obviously different months have a different number of days, so you can't just divide days by a given number. Also, are you talking about complete months or part months - for example, how many months between 30-Apr-2018 and 01-May-2018. Obviously only a day, but could also be seen as a month.

Probably going to need to know more info about what you actually need.

Generally speaking though you will be working with a DateTime object, and you can use the ParseExact method to get that from your strings:

var date1 = DateTime.ParseExact("01.01.2010", "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);
var date2 = DateTime.ParseExact("01.05.2009", "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);

Open in new window

Once you've got your dates, you can do various calculation on them. If you just need a simple 'months' difference and don't care about the days, then something like this may help:

var diff = (date1.Month - date2.Month) + 12 * (date1.Year - date2.Year); // gives a result of 8

Open in new window

0
 
it_saigeDeveloperCommented:
Do you mean something like this:
using System;
using System.Globalization;
using System.Linq;

namespace EE_Q29097207
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine($"01.05.2009 was {"01.05.2009".TotalMonths("01.01.2010")} months ago from 01.01.2010");
			Console.ReadLine();
		}
	}

	static class Extensions
	{
		public static int TotalMonths(this string start, string end)
		{
			DateTime startDate, endDate;
			int result;
			var formats = (from month in Enumerable.Range(1, 2)
						   from day in Enumerable.Range(1, 2)
						   from year in Enumerable.Range(1, 4)
						   from delimeter in new[] { '.', '/' }
						   select $"{new string('M', month)}{delimeter}{new string('d', day)}{delimeter}{new string('y', year)}").ToArray();
			try
			{
				DateTime.TryParseExact(start, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out startDate);
				DateTime.TryParseExact(end, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out endDate);
				result = (startDate.Year * 12 + startDate.Month) - (endDate.Year * 12 + endDate.Month);
				if (result < 0)
					result *= -1;
			}
			catch (Exception)
			{
				return 0;
			}
			return result;
		}
	}
}

Open in new window

Which produces the following output -Capture.PNG-saige-
0
 
AdnanAuthor Commented:
Ok, I can try to explain the whole scenario.
I would like to calculate the work experience of an emplye.
And the challenge is to calculate the date back to 01.05 (may).
Let's say that my start date for new job is 01.01.2010, then it will be calculated back in time to 01.05, which will actually be 01.05.2009.
The rule is that regardless of when an employee starts working, they must calculate their work experience from their startdate (01.01.2010) and back in time to 01.05.....so that means their workexpirence will be counted from the 01.05 and not the actually startdate...
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
Chris StanyonCommented:
Not sure I follow that at all!

The code we've provided shows you a couple of options on how to calculate the number of months between 2 dates. Is that notwhat you need ??
0
 
it_saigeDeveloperCommented:
Just change around the filter formats in the examples so that they are dd/MM/yyyy (or any derivative thereof); e.g. -
using System;
using System.Globalization;
using System.Linq;

namespace EE_Q29097207
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine($"01.05.2009 was {"01.05.2009".TotalMonths("01.01.2010")} months ago from 01.01.2010");
			Console.WriteLine($"05/01/2009 was {"05/01/2009".TotalMonths("01/01/2010")} months ago from 01/01/2010");
			Console.WriteLine($"1.5.09 was {"1.5.09".TotalMonths("1.1.10")} months ago from 1.1.10");
			Console.WriteLine($"5/1/09 was {"5/1/09".TotalMonths("1/1/10")} months ago from 1/1/10");
			Console.ReadLine();
		}
	}

	static class Extensions
	{
		public static int TotalMonths(this string start, string end)
		{
			DateTime startDate, endDate;
			int result;
			var formats = (from month in Enumerable.Range(1, 2)
						   from day in Enumerable.Range(1, 2)
						   from year in Enumerable.Range(1, 4)
						   from delimeter in new[] { '.', '/' }
						   select delimeter.Equals('.') ? 
								$"{new string('d', day)}{delimeter}{new string('M', month)}{delimeter}{new string('y', year)}" :
								$"{new string('M', month)}{delimeter}{new string('d', day)}{delimeter}{new string('y', year)}").ToArray();
			try
			{
				DateTime.TryParseExact(start, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out startDate);
				DateTime.TryParseExact(end, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out endDate);
				result = (startDate.Year * 12 + startDate.Month) - (endDate.Year * 12 + endDate.Month);
				if (result < 0)
					result *= -1;
			}
			catch (Exception)
			{
				return 0;
			}
			return result;
		}
	}
}

Open in new window

Produces the following output -Capture.PNG-saige-
0
 
AdnanAuthor Commented:
@Chris Stanyon i need to calculate number of months back to 01.05. Whatever startdate is, date have to be calculated back in months to 01.05....

So f.ex startdate is 01.01.2010, then the date have to be calculated back to 01.05.2009, because work experience always counts from 01.05....
0
 
it_saigeDeveloperCommented:
You keep providing the parameters for the equation but you are not specifying the result if our result is different from your expectations.

How about this, how many months should be the result of from startdate 01.01.2010 calculated back to 01.05.2009?  What is the value you are expecting to see?

-saige-
0
 
Chris StanyonCommented:
Just to echo it_saige's comment. What we've provided already does this. If you run my code it will return a result of 8, which by my understanding is correct. There are 8 months between 01.05.2009 and 01.01.2010.

Are you expecting something different ??
0
 
AdnanAuthor Commented:
the result should be 8 months, iam testing your code but its giving me 42 as result ?

public int calcTest(string ansattId, string ansattdato, string sluttdato, string diffinday,string diffindaysalder, string dto1, string dtoalder)
        {
            DateTime startDate, endDate;
            int result;
            var formats = (from month in Enumerable.Range(1, 2)
                           from day in Enumerable.Range(1, 2)
                           from year in Enumerable.Range(1, 4)
                           from delimeter in new[] { '.', '/' }
                           select delimeter.Equals('.') ?
                                $"{new string('d', day)}{delimeter}{new string('M', month)}{delimeter}{new string('y', year)}" :
                                $"{new string('M', month)}{delimeter}{new string('d', day)}{delimeter}{new string('y', year)}").ToArray();
            try
            {
                DateTime.TryParseExact(ansattdato, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out startDate);
                DateTime.TryParseExact(sluttdato, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out endDate);
                result = (startDate.Year * 12 + startDate.Month) - (endDate.Year * 12 + endDate.Month);
                if (result < 0)
                    result *= -1;
            }
            catch (Exception)
            {
                return 0;
            }
            return result;

        }

Open in new window

0
 
it_saigeDeveloperCommented:
What are the parameters you are providing; e.g. -
var blah = calcTest("a", "b", "c", "d", "e", "f", "g");

Open in new window

-saige-
0
 
AdnanAuthor Commented:
calcTest(string ansattId, string ansattdato, string sluttdato, string diffinday,string diffindaysalder, string dto1, string dtoalder)

Open in new window


ansattdato is the startdate, the day employe start working...
sluttdato is the enddate...

both ansattdato and sluttdato is string parameters

other parameters are not in use yet...
0
 
it_saigeDeveloperCommented:
What are the actual values you are using?  Are they the same as what you have provided already?  I am going to assume that they are:
using System;
using System.Globalization;
using System.Linq;

namespace EE_Q29097207
{
	class Program
	{
		static void Main(string[] args)
		{
			var instance = new Program();
			Console.WriteLine($"01.05.2009 was {instance.calcTest("", "01.05.2009", "01.01.2010", "", "", "", "")} months ago from 01.01.2010");
			Console.WriteLine($"05/01/2009 was {instance.calcTest("", "05/01/2009", "01/01/2010", "", "", "", "")} months ago from 01/01/2010");
			Console.WriteLine($"1.5.09 was {instance.calcTest("", "1.5.09", "1.1.10", "", "", "", "")} months ago from 1.1.10");
			Console.WriteLine($"5/1/09 was {instance.calcTest("", "5/1/09", "1/1/10", "", "", "", "")} months ago from 1/1/10");
			Console.ReadLine();
		}

		public int calcTest(string ansattId, string ansattdato, string sluttdato, string diffinday, string diffindaysalder, string dto1, string dtoalder)
		{
			DateTime startDate, endDate;
			int result;
			var formats = (from month in Enumerable.Range(1, 2)
						   from day in Enumerable.Range(1, 2)
						   from year in Enumerable.Range(1, 4)
						   from delimeter in new[] { '.', '/' }
						   select delimeter.Equals('.') ?
								$"{new string('d', day)}{delimeter}{new string('M', month)}{delimeter}{new string('y', year)}" :
								$"{new string('M', month)}{delimeter}{new string('d', day)}{delimeter}{new string('y', year)}").ToArray();
			try
			{
				DateTime.TryParseExact(ansattdato, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out startDate);
				DateTime.TryParseExact(sluttdato, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out endDate);
				result = (startDate.Year * 12 + startDate.Month) - (endDate.Year * 12 + endDate.Month);
				if (result < 0)
					result *= -1;
			}
			catch (Exception)
			{
				return 0;
			}
			return result;

		}
	}

	static class Extensions
	{
		public static int TotalMonths(this string start, string end)
		{
			DateTime startDate, endDate;
			int result;
			var formats = (from month in Enumerable.Range(1, 2)
						   from day in Enumerable.Range(1, 2)
						   from year in Enumerable.Range(1, 4)
						   from delimeter in new[] { '.', '/' }
						   select delimeter.Equals('.') ? 
								$"{new string('d', day)}{delimeter}{new string('M', month)}{delimeter}{new string('y', year)}" :
								$"{new string('M', month)}{delimeter}{new string('d', day)}{delimeter}{new string('y', year)}").ToArray();
			try
			{
				DateTime.TryParseExact(start, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out startDate);
				DateTime.TryParseExact(end, formats, CultureInfo.CurrentCulture, DateTimeStyles.None, out endDate);
				result = (startDate.Year * 12 + startDate.Month) - (endDate.Year * 12 + endDate.Month);
				if (result < 0)
					result *= -1;
			}
			catch (Exception)
			{
				return 0;
			}
			return result;
		}
	}
}

Open in new window

Gives me the same results as previously shown -Capture.PNG-saige-
0
 
Gustav BrockCIOCommented:
This is quite simple to achieve:

string start = "01.01.2010";
DateTime startDate = DateTime.Parse(start);
DateTime backDate = startDate.AddMonths((5 - startDate.Month - 12) % 12);

Console.WriteLine(backDate.ToString());
// 2009-05-01 00:00:00

Open in new window

0
 
AdnanAuthor Commented:
thanks, it worked, i was passing wrong parameters.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 5
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now