Add Days methods - c#

I have to create a class that includes 3 methods.
1st - It shows current date
2nd - current date + 7days
3rd - current date - 7days.
I had completely dealing with dates in C # so i created sth that :
public class Date
{
private DateTime date = DateTime.Now;
public DateTime Now()
{
return date;
}
public DateTime AktuPlusOne ()
{
DateTime date = DateTime.Now.AddDays(7);
return date;
}
public DateTime AktuMinusOne()
{
DateTime date = DateTime.Now.AddDays(-7);
return date;
}
}
Is it ok or not ? It works fine, but I care about good habits .

No need to create additional method as framework already provides this functionality out of box DateTime.Now.AddDays(numberOfDays). However, if you really want to create a generic method for your requirement, just create one instead of three methods.
public DateTime AddDaysToToday(int days)
{
return DateTime.Now.AddDays(days);
}
DateTime today = AddDaysToToday(0);
DateTime todayPlusSeven = AddDaysToToday(7);
DateTime todayMinusSeven = AddDaysToToday(-7);

Related

Storing Utc Time in Getter/Setter Property

Currently, I am storing theDateTime with the DeliveryDate getter/setter. However, I'm having issues storing this in UTC time. I've done some research on this and tried DateTimeKind.Utc but can't get that to work correctly. How can I get DeliveryDate to store the DateTime in UTC time?
My Code:
public partial class shippingInfo
{
public System.Guid EmailConfirmationId {get; set; }
public Nullable<System.DateTime> DeliveryDate {get; set; }
}
Update: Added Implementation:
DeliveryExpirationRepository.Add(new DeliveryPendingConfirmation
{
EmailConfirmationId = newGuid,
DeliveryDate = DateTime.Now.AddHours(48),
});
To make a DateTime store a UTC value, you must assign it a UTC value. Note the use of DateTime.UtcNow instead of DateTime.Now:
DeliveryExpirationRepository.Add(new DeliveryPendingConfirmation
{
EmailConfirmationId = newGuid,
DeliveryDate = DateTime.UtcNow.AddHours(48),
});
The DateTime.UtcNow documentation says:
Gets a DateTime object that is set to the current date and time on this computer, expressed as the Coordinated Universal Time (UTC).
The DateTime.Now documentation says:
Gets a DateTime object that is set to the current date and time on this computer, expressed as the local time.
You might want to use DateTimeOffset instead. It always stores an absolute point in time, unambiguously.
You can add a code to the setter method to check if value is not in UTC and convert this value to UTC:
public class shippingInfo {
public System.Guid EmailConfirmationId { get; set; }
private Nullable<System.DateTime> fDeliveryDate;
public Nullable<System.DateTime> DeliveryDate {
get { return fDeliveryDate; }
set {
if (value.HasValue && value.Value.Kind != DateTimeKind.Utc) {
fDeliveryDate = value.Value.ToUniversalTime();
}
else {
fDeliveryDate = value;
}
}
}
}
In this case, you don't need to care how a value of this property is set. Or you can use the DateTime.ToUniversalTime method to convert any date to UTC where you set a value of the property.

Identifier expected,String is a keyword

I have a php code like this,going to convert it in to C#.
function HuntingDate()
{
Global $nameofselectbox,$startYear,$endYear,$year,
$startDate,$endDate,$startMounth,$endMounth,$startDay,$endDay;
$today = getdate();
$year=$today['year'];
$mounth=$today['mon'];
$day=$today['mday'];
Here is my try( I tried to use enum for this)
public enum HuntingDate{string StartYear,string EndYear,string Year,string StartDate,string EndDate,string StartMonth,string EndMonth,stirng StartDay,string EndDay}
Can i do thisone with enum ? i got the error "Identifier expected,String is a keyword"
No not with enum, you should use a class for this:
public class HuntingDate
{
string StartYear;
string EndYear;
string Year;
string StartDate;
string EndDate;
string StartMonth;
string EndMonth;
string StartDay;
string EndDay;
}
you then have further things to consider:
Strings are not ideal for date type data, for this consider using DateTime - with this you can merge the year, month and day values into one property:
public class HuntingDate
{
public DateTime StartDateTime;
public DateTime EndDateTime;
}
Classes are used to define the structure of an object, as my example stands you would need to create an instance of the class in order to use it:
HuntingDate huntingDate = new HuntingDate();
with this you have to consider where you want to have access to it. If you need a global accessible instance you could initialise the class at a global scope level, or consider using a static class (though it should be noted that these values would be persisted across the whole application):
public static class HuntingDate
{
public static string Something;
}
I would strongly suggesting doing some reading on C# (get a book!) if you want to do this more seriously you should get a solid grasp of the basics of C#
I guess you want the (string) values "StartYear", "EndYear" and so on as values of an enum.
You cannot do that: an enum is always based on some integer type.
I think you would be better off using the DateTime type for the start and end dates, and wrap it all in a class something like this:
public class HuntingDate
{
public HuntingDate(DateTime start, DateTime end)
{
_start = start;
_end = end;
}
public DateTime End
{
get
{
return _end;
}
}
public DateTime Start
{
get
{
return _start;
}
}
private readonly DateTime _start;
private readonly DateTime _end;
}
No, You can do this with enum. By default the underlying type of each element in the enum is int.
You can specify another integral numeric type by using a colon, as
shown in the example below. For a full list of possible types, see enum (C#
Reference).
Example:
enum Months : byte { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec };
You can use struct or class type for this purpose.
public struct HuntingDate
{
int StartYear;
int StartMonth;
int StartDay;
int Year;
DateTime StartDate; // it smells like you are storing date then why do
// you not use DateTime rather than these..
DateTime EndDate;
int EndYear;
int EndMonth;
int EndDay;
}
If your Year it not necessary then it can be shorten as:
public struct HuntingDate
{
public DateTime StartDate;
public DateTime EndDate;
}
other wise go for the full values including Year.
bear i mind i don't know php from... well php...
function HuntingDate()
{
Global $nameofselectbox,$startYear,$endYear,$year,
$startDate,$endDate,$startMounth,$endMounth,$startDay,$endDay;
$today = getdate();
$year=$today['year'];
$mounth=$today['mon'];
$day=$today['mday'];
... rest of code
}
I'm guesstimating you'll need a class (and not an enum)
public class HuntingDate()
{
string NameOfSelectbox;
DateTime endDate;
rest of code ...
}
I saw there are lots of answers,WHAT IS THE BEST ANSWER ?

How to handle vague dates in .Net

I have a system that takes information from an external source and then stores it to be displayed later.
One of the data items is a date. On the source system they have the concept of a fuzzy date i.e. not accurate to a specific day or sometimes not to a month as well. So I get dates in the format:
dd/mm/yyyy
mm/yyyy
yyyy
I can parse these to DateTime objects and work with these but when rendering later I need to be able to determine the accuracy of the date since parsing "2010" will result in a date of "01/01/2010". I want to show just the year so need to know it's original accuracy.
I've mocked up a quick class to deal with this:
public class FuzzyDate
{
public DateTime Date { get; set; }
public DateType Type { get; set; }
}
public enum DateType
{
DayMonthYear,
MonthYear,
Year
}
This will do the job for me and I can do something on the parse to handle it but I feel like this is probably quite a common problem and there is probably an existing cleaner solution.
Is there something built into .Net to do this? I had a look at the culture stuff but that didn't quite seem right.
Any help would be appreciated.
To answer your question: There is nothing built into .NET to handle this gracefully.
Your solution is as valid as any I've seen. You will probably wish to embellish your class with overrides to the ToString() method that will render your date appropriately based on the DateType.
Here are a couple other threads that attempt to address this question:
Strategy for Incomplete Dates
Implementing a "Partial Date" object
Good luck!
If your data type will always handle specific periods of time (i.e. the year 1972 is a specific period of time, but the 4th of July is not specific), you can store your data as a start time and time span.
If your date was "1972", the start date would be 19720101 and the time span would be 366 days.
If your date was "07/1972", the start date would be 19720701 and the time span would be 31 days.
If your date was "04/07/1972", the start date would be 19720704 and the time span would be 1 day.
Here's a possible implementation:
public struct VagueDate
{
DateTime start, end;
public DateTime Start { get { return start; } }
public DateTime End { get { return end; } }
public TimeSpan Span { get { return end - start; } }
public VagueDate(string Date)
{
if (DateTime.TryParseExact(Date, "yyyy", null, 0, out start))
end = start.AddYears(1);
else if (DateTime.TryParseExact(Date, "MM/yyyy", null, 0, out start))
end = start.AddMonths(1);
else if (DateTime.TryParseExact(Date, "dd/MM/yyyy", null, 0, out start))
end = start.AddDays(1);
else
throw new ArgumentException("Invalid format", "Date");
}
public override string ToString()
{
return Start.ToString("dd/MM/yyyy") + " plus " + Span.TotalDays + " days";
}
}
As I started to read your problem, I rapidly came to the conclusion that the answer was to implement your own FuzzyDate class. Lo and behold, that's exactly what you've done.
I can imagine that you might want to add functionality to this over time (such as comparisons that take into account the DateType).
I don't believe there's anything that will inherently help you in the .NET Framework, so I think you're doing the right thing.
I think you're going down the right route. There is no concept of a 'fuzzy' date or partial date, you will need to build your own.
You will likely need more constructor methods, for example
public FuzzyDate(int year)
{
Date = new DateTime(year,1,1); // 1 Jan yy
Type = DateType.Year;
}
public FuzzyDate(int year, int month)
{
Date = new DateTime(year, month, 1); // 1 mm yy
Type = DateType.MonthYear;
}
public FuzzyDate(int year, int month, int day)
{
Date = new DateTime(year, month, day); // dd mm yy
Type = DateType.DayMonthYear;
}
Hope this helps,
Kevin
It seems to me that your approach is right. Its true that .NET DateTime support multiple formats but I guess that given that all of them are supported with a concept of steps (nanoseconds), then will be related to specific date AND time.
One thing I would do differently is use null-able values (or use -1 for null semantics) for month and day to indicate what data was collected. Then I would have a factory method that would take a DateType param and return a DateTime. This method would throw and exception if only the year was available and the client code tried to create a DateType.DayMonthYear.
public class FuzzyDate
{
int _year;
int? _month;
int? _day;
public DateTime Date { get; set; }
public DateType Type { get; set; }
public DateTime GetDateTime(DateType dateType) { // ...
}
public enum DateType
{
DayMonthYear,
MonthYear,
Year
}
This might seem a bit over the top but the approach would explicitly store the original data and only represent "faked" DateTime objects when requested. If you were to persist a DateTime object internally along with a DateType enum you would lose some resolution.
As far as I am aware there is nothing built into .NET for this, the solution I'd go for is one based upon nullable values, something like this.
public class FuzzyDate
{
private int Year;
private int? Month;
private int? Day;
public FuzzyDate(int Year, int? Month, int? Day)
{
this.Year = Year;
this.Month = Month;
this.Day = Day;
}
public DateType DateType
{
get
{
if(Day.HasValue && Month.HasValue)
{
return DateType.DayMonthYear;
}
else if(Month.HasValue)
{
return DateType.MonthYear;
}
else
{
return DateType.Year;
}
}
}
public DateTime Date
{
get
{
return new DateTime(Year, Month.GetValueOrDefault(1), Day.GetValueOrDefault(1));
}
}
}
public enum DateType
{
DayMonthYear,
MonthYear,
Year
}
You could create your own structure (user-defined type) based on the datetime that would allow 00 for month, and 00 for day... And then also implement icomparable, so you can do math/comparrisons on it.
http://msdn.microsoft.com/en-us/library/k69kzbs1%28v=vs.71%29.aspx
http://msdn.microsoft.com/en-us/library/system.icomparable.aspx

How to test logic which is dependent on current date [duplicate]

This question already has answers here:
Unit Testing: DateTime.Now
(22 answers)
Closed last year.
I have this method which is dependent on current date. It checks if today is Sun, Mon, Tue or Wed, then it gives 5 days of lead time for arrival of shipped items. If its Thur, Fri or Sat then it gives 6 days of lead time to account for the weekend.
private DateTime GetEstimatedArrivalDate()
{
DateTime estimatedDate;
if (DateTime.Now.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = DateTime.Now.Date.AddDays(6);
}
else
{
estimatedDate = DateTime.Now.Date.AddDays(5);
}
return estimatedDate;
}
The actual estimation logic is more complex. I have simplified it for the purpose of this question. My question is how do I write a unit test for something like this which depends on todays date?
You need to pass the current date in as a parameter:
private DateTime GetEstimatedArrivalDate(DateTime currentDate)
{
DateTime estimatedDate;
if (currentDate.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = currentDate.AddDays(6);
}
else
{
estimatedDate = currentDate.AddDays(5);
}
return estimatedDate;
}
In real code you call it like this:
DateTime estimatedDate = GetEstimatedArrivalDate(DateTime.Now.Date);
Then you can test it as follows:
DateTime actual = GetEstimatedArrivalDate(new DateTime(2010, 2, 10));
DateTime expected = ...;
// etc...
Note that this also fixes a potential bug in your program where the date changes between consecutive calls to DateTime.Now.
Generally speaking, you'd want to abstract the method of obtaining the current date and time behind an interface, eg:
public interface IDateTimeProvider
{
DateTime Now { get; }
}
The real service would be:
public class DateTimeProvider: IDateTimeProvider
{
public DateTime Now
{
get
{
return DateTime.Now;
}
}
}
And a test service would be:
public class TestDateTimeProvider: IDateTimeProvider
{
private DateTime timeToProvide;
public TestDateTimeProvider(DateTime timeToProvide)
{
this.timeToProvide = timeToProvide;
}
public DateTime Now
{
get
{
return timeToProvide;
}
}
}
For services that require the current time, have them take an IDateTimeProvider as a dependency. For the real thing, pass a new DateTimeProvider(); when you're a component, pass in a new TestDateTimeProvider(timeToTestFor).
Make your class take an IClock parameter (via constructor or property)
interface IClock
{
DateTime Now { get; }
}
You can then use a fake implementation for testing
class FakeClock : IClock
{
DateTime Now { get; set }
}
and a real implementation the rest of the time.
class SystemClock : IClock
{
DateTime Now { get { return DateTime.Now; } }
}
I would suggest doing this as Mark suggests, but with the addition of a overloaded call for production use that takes no parameter and uses DateTime.Now
private DateTime GetEstimatedArrivalDate()
{
return GetEstimatedArrivalDate(DateTime.Now);
}
private DateTime GetEstimatedArrivalDate(DateTime currentDate)
{
DateTime estimatedDate;
if (currentDate.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = currentDate.AddDays(6);
}
else
{
estimatedDate = currentDate.AddDays(5);
}
return estimatedDate;
}
One "common" way of doing so is to "fake" the current system date (that can be done in several ways) and then test your code on "known" dates.
Another interesting way is to change your implementation slightly to:
private DateTime GetEstimatedArrivalDate()
{
return GetEstimatedArrivalDate(DateTime.Now);
}
private DateTime GetEstimatedArrivalDate(DateTime forDate)
{
DateTime estimatedDate;
if (forDate.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = forDate.Date.AddDays(6);
}
else
{
estimatedDate = forDate.Date.AddDays(5);
}
return estimatedDate;
}
And then use the method with a parameter to test on "immediate" dates.
Seems like there are a limited enough number of cases that you could test them each explicitly. The method depends on today's date, but the output depends only on the day of week, and every date has a day of week.
You could pass in a delegate that returns DateTime.Now during normal execution, and then in your test pass in another delegate that returns a fixed date, and assert your result based on that.
I'll give the controversial answer, don't test it.
The logic is trivial and it has zero dependencies, i believe in good code coverage but not when it increases complexity for no real gain.

Format a string to display the Date correctly

I need help converting this string --> 20090727 10:16:36:643 to --> 07/27/2009 10:16:36
The original date and time are being returned by the SynchronizationAgent.LastUpdated() function, which returns a String in the above format.
Original question:preserved for reference
I have this -->
HUD.LastSyncDate = mergeSubscription.SynchronizationAgent.LastUpdatedTime;
Which is setting a property that looks like this -->
public static string LastSyncDate
{
get { return _lastSyncDate; }
set
{
_lastSyncDate = String.Format(CultureInfo.InvariantCulture,"{0:G}", value);
}
}
Unfortunately, with or without the String.Format the date that is displayed looks like this --> 20090727 10:16:36:643
I have tried multiple variations to Format it the way I want. What am I missing?
Based on the below suggestions(Mostly Joel's), I implemented the suggested changes but I am still getting a "String is not a valid DateTime error"
I also tried implementing this -->
HUD.LastSyncDate = DateTime.ParseExact(mergeSubscription.SynchronizationAgent.LastUpdatedTime,"yyyyMMdd HH:mm:ss:fff",CultureInfo.InvariantCulture);
but still nothing.
HUD.LastSyncDate = DateTime.Parse(mergeSubscription.SynchronizationAgent.LastUpdatedTime).ToString("MM/dd/yyyy")
You can put any format string you want there. But it sounds like what you really want is something more like this:
private static DateTime _lastSyncDate;
public static DateTime LastSyncDate
{
get { return _lastSyncDate; }
set { _lastSyncDate = value;}
}
public static string LastSyncDateString
{
get { return LastSyncDate.ToString("MM/dd/yyyy"); }
}
Keep it as a datetime in the background and just use the string property for display.
It appears to me that LastUpdatedTime is actually a string (since you can do the assignment) not a DateTime. In that case, the format applied won't do anything. You'll want to parse the LastUpdatedTime into a DateTime then reformat into the format that you want before assigning it to your string.
DateTime lastUpdated = DateTime.Parse( mergeSubscription.SynchronizationAgent.LastUpdatedTime );
HUD.LastSyncDate = string.Format( "{0:G}", lastUpdated );
public static string LastSyncDate { get; set; }
Note that you may need to use ParseExact instead.
DateTime lastUpdated = DateTime.ParseExact( "yyyyMMdd HH:mm:ss:fff",
...,
CultureInfo.InvariantCulture );
What do you want to do? You get a string, pass it to String.Format() and store it in a string field. Do you want to reformat the string? In this case you have to parse the string back to DateTime and format this value again.
DateTime dateTime;
if (DateTime.TryParse(value, out dateTime))
{
lastSyncDate = String.Format(CultureInfo.InvariantCulture,"{0:G}", dateTime);
}
else
{
HandleInvalidInput(value);
}

Categories