UWP/C# Date Storage in a Variable - c#

Now, ive bumped into so many different responses to the usage of Date in C#
Ranging from using:
DateTime.Parse
Date.Now
etc. There seems to me a huge amount of ways to use the time date funtion. What i need to do is Read the Day, Month and Year from say today (assuming Date.Now?) and store these values individually so that they can be referenced throughout the entire budget.
The way i was looking at doing this was by having the DateTimeStorage Class in its own Classes Folder. That way, i can reference it at any point throughout the entire project right?
The issue i have bumped into is that i get an error immediately with the following two lines within the class:
class DateTimeStorage
{
String stringDate;
DateTime dateValue = DateTime.Parse(stringDate);
}
According to this, stringDate has an error
a field initialiser cannot reference the non-static field
Now, i was going to close the Class by storing the string values like below:
class DateTimeStorage
{
String stringDate;
DateTime dateValue = DateTime.Parse(stringDate);
String day = datevalue.Day.ToString();
//etc
}
This doesnt work either, "dateValue does not exist in the current context"
Now, im completely stumped and not sure how best to approach this. There are so many different ways ive seen to do dates. Its hard to know if any of them work the way i need them to.
Would anyone have any suggestions? I need to store the variables as strings as they are going to be used through the entire project to populate fields etc.
Any help would be hugely appreciated

What about a static class to store the current date. You could modify this such that the date is able to be updated from elsewhere in the code but this is the simplest approach that initializes the date to Now on program start up.
using System;
namespace ClassLibrary3
{
public static class StaticDate
{
static StaticDate()
{
//Initialize Date
var date = DateTime.Now;
Year = date.Year;
Month = date.Month;
Day = date.Day;
}
public static readonly int Year;
public static readonly int Month;
public static readonly int Day;
}
public class SomeOtherClass
{
public void MethodThatNeedsDate()
{
var year = StaticDate.Year;
var day = StaticDate.Day;
}
}
}

Related

List stored in a session wrapper remains with Count 0 although method called to add item into it

I am a beginner, learning ASP.Net, so apologies in advance if the codes are really messy, I am also still learning the sessions and some of the terms in .Net. Anyway, I am using session to retain values during postback. However, I think I am not coding them properly, I am having difficulty understanding the whole session in a list concept thingy, I understand how session works, but session and generic list is so confusing. Anyway, this is the code.
public class MySessionWrapper
{
private MySessionWrapper()
{
}
private static List<DateTime> _Week_1;
public static List<DateTime> A_Week_1
{
get
{
_Week_1 = (List<DateTime>) HttpContext.Current.Session["A_Week_1"];
if(_Week_1 == null)
{
_Week_1 = new List<DateTime>();
}
return (List<DateTime>)_Week_1;
}
}
public static void AddWeek1(DateTime add_date)
{
A_Week_1.Add(add_date);
}
}
//and I am calling it from here using something like this
if (weeknum == 1)
{
MySessionWrapper.AddWeek1(date1);
}
The thing is, I noticed that the MySessionWrapper.AddWeek1 method remains as 0 although there are values hitting the weeknum == 1. It goes to the session wrapper class does not add the value at all into the List. I would really need some guidance on understanding session with generic list and could someone point what exactly am I doing wrong here.
Hi guys, I have edited the code again like what Gaurav pointed out, but I am getting stuck again, this time the list has already been initialized but with a certain number of count in it. Maybe I can explain better what I want to do.
I have a drop down list that contains the months. So, if a user selects February, the program would actually divide the dates within the month into respective weeks, weekofDay being Monday. So for example, in February, it should be
Months -- Week Start Date ---- Week End Date
Week1 - 2/1/2019 12:00:00 AM - 2/3/2019 12:00:00 AM
Week2 - 2/4/2019 12:00:00 AM - 2/10/2019 12:00:00 AM
Week3 - 2/11/2019 12:00:00 AM - 2/17/2019 12:00:00 AM
Week4 - 2/18/2019 12:00:00 AM - 2/24/2019 12:00:00 AM
Week5 - 2/25/2019 12:00:00 AM - 2/28/2019 12:00:00 AM
So, this now works fine after the page load and I choose February, but again I would like to see for March and the page gets refreshed but the Week Start Dates remains at February ones, the Week End Dates gets updated accordingly.
Is this something to do with the sessions ?
I recommend rewriting your method like so:
public static List<DateTime> A_Week_1
{
get
{
var week1 = (List<DateTime>)HttpContext.Current.Session["A_Week_1"];
if(week1 == null)
{
week1 = new List<DateTime>();
HttpContext.Current.Session["A_Week_1"] = week1;
}
return week1;
}
}
I've ditched private static List<DateTime> _Week_1; since it's not useful or necessary.
If you need to, you can add a setter method to "reset" the value:
public static List<DateTime> A_Week_1
{
get
{
var week1 = (List<DateTime>)HttpContext.Current.Session["A_Week_1"];
if(week1 == null)
{
week1 = new List<DateTime>();
HttpContext.Current.Session["A_Week_1"] = week1;
}
return week1;
}
set
{
HttpContext.Current.Session["A_Week_1"] = value;
}
}
Then you can either reset it by setting A_Week_1 = null (thereby forcing the getter to create a new list next time you access the getter), or you can manually set it to a new list (e.g. A_Week_1 = new List<DateTime>();).
Of course, you could also "reset" by simply clearing the list: A_Week_1.Clear();

Compare two different hours using objectValue and return false if the different is 6 hours

My class has a date register a property.
So, a create a another class that is a specification, where a validade some business rules.
Here's the attempt code:
public class InfoPointingCannotBeSixOurLater : ISpecification<InfoPointing >
{
public bool IsSatisfiedBy(InfoPointing infopointing)
{
return DateTime.Now.Hour - infopointing.Dateregister.Hour>=6;
}
}
Rule:
The time that the infopointing was registered cannot be greater than 6 when compared to the current date.
The class is ok, my problem is how can i return false if that rule was not Satisfied
Any ideias how can i solve that?
Your problem is that DateTime.Now.Hour returns an integer disregarding the date. When infopointing.Dateregister is today, you have no problem, but when it is different dates, your logic breaks. What you need is to compute the difference between two dates and time and get the amount of hours that have elapsed. Try this:
return (DateTime.Now - infopointing.Dateregister).Hours>=6;
Use this code:
public class InfoPointingCannotBeSixOurLater : ISpecification<InfoPointing >
{
public bool IsSatisfiedBy(InfoPointing infopointing)
{
return DateTime.Now.Subtract(infopointing.Dateregister).TotalHours >=6;
}
}

Restrict DateTime with a minimum date and time (not fall below 00:00)

I am using DateTime and it's methods like DateTime.AddMinutes etc.
Is there a way to make DateTime throw an Exception when adding a negative number of minutes/seconds etc that make the time fall beneath 00:00 and not turn the time to 23:59?
At Domain Model Level
At the domain model you could a Decorator/Wrapper class. Just use a class that has a private DateTime object and pass through every method of that object that remains unaltered and implement those that are altered, essentially just by writing:
public bool Equals(DateTime dt){
return this.dateTime.Equals(DateTime dt);
}
There are however a couple of issues with this:
In the above example you might want to compare your DateTime object with itself, but that won't be possible.
DateTime has certain attributes eg. its serializable that you may lose until adding a fair bit of time to this.
At Controller Level
Assuming you are implementing this in an applicatino with MVC setup, you probably have some validation within your controller. That should be able to handle these cases.
I'd recommend this approach, as you can reject any case where the Date part of the datetime does not match or is less than the original date.
You can try a extension method like so:
public static class MyDateTimeChecker
{
public static bool CheckTime(this DateTime dt, int minutes)
{
if (dt.Day > dt.AddMinutes(minutes).Day)
return false;
else
return true;
}
}
I placed Day since in your question you wanted to know if it would fall bellow 00:00 or back to the previous day at 23:59,so this is one way to go.
Then in your code you can use it like this:
DateTime dt = DateTime.Now;
if(dt.CheckTime(-1440))
{
//if true your negative number was in range
//so use it if you like.
}
else
}
//oops too much
}

Adding a number to variable names in C#

My question is sort of like the one found here:
How do I name variables dynamically in C#?
However its a bit different so I'm wondering if its possible.
I'm trying to read in a bunch of strings from a .settings file.
I have them all named Time1, Time2,Time3 etc...
I want the User to be able to add more Times to the file so there could be Time100 or more.
I have a Size in the settings file that will keep track of the amount of Time Variables.
I want to write something that will read in all of the Time strings. I think it would be silly to pre-fill the .settings file with 100 Time Variables so I know they are there and then manually read in each one.
So I'm wondering if there is a way where I can read in Timei or Time+i where I is an integer that I can put in a loop that will find them all.
(note that the data is string not time, its just going to be converted to days of the week)
Such as: (Days is from ApplicationSettingsBase [aka file add new Settings1.settings]
public static int AvDaysIndex = Days.Default.Size; //This holds the number of items in Days
public static DayOfWeek[] AvailableDays = new DayOfWeek[AvDaysIndex]; //This is where I wants to read in all the variables Aka Time1 Time2 Times3
public ReadInDays() //Reads in from the .settings File
{
if(AvDaysIndex>0) // Makes sure there is something in Days to read
{
int I=0;
//I can Manually do the following
AvailableDays[I++] = Days.Default.Time1;
AvailableDays[I++] = Days.Default.Time2;
AvailableDays[I++] = Days.Default.Time3; //etc...
//Is there a way to do something like this
for (int i = 0; i < AvDaysIndex; i++) //reads in each time
{
AvailableDays[i] = Days.Default.Time +i;//where I would be added to the variable name to find it?
//Or something like
AvailableDays[i] = Days.Default.Time(I.tostring())
}
}
}
Hopefully all that at least makes it clear what I'm trying to do.
Edit - I'm starting to think my issue is actually with the .settings file. and that if I just read values in from another file type where the values don't have names I can easily read them in even though there is a variable number of elements in the file.
Solution -
for (int i = 0; i < Index; i++)
{
AvailableDays[i] = getFromFile(_Days.Default.Properties["Time" + (i+1).ToString()].DefaultValue.ToString());
AvailableTimes[i] = Convert.ToDateTime(_Times.Default.Properties["Time" + (i + 1).ToString()].DefaultValue);
}
It was all in figuring out how to read in from the .settings file and instead of reading it in directly aka Days.Default.Time1; I had to to do a generic lookup from Days.Default.Properties and then I could create a dynamic name and find it. You guys probably were trying to tell me how to do this, I just didn't understand.
Thanks again to all those that helped.
I would use a hashtable/dictionary to store the Days.Default.TimeX variations
hashtable["Time1"]...hashtable["TimeN"]
As already mentioned a hashtable or a dictionary would probably serve you best. If you go the dictionary route you can create a string/int indexer on the class and you would be able to alter your code slightly:
http://msdn.microsoft.com/en-us/library/2549tw02%28v=vs.80%29.aspx - Example of creating indexer on a class:
Example Indexer Class:
public class Default
{
private Dictionary<int, DayOfWeek> _values = new Dictionary<int,DayOfWeek>();
public DayOfWeek this[int index]
{
get
{
if (_values.ContainsKey(index))
return _values[index];
else
return null;
}
set
{
_values[index] = value;
}
}
}
Original:
AvailableDays[i] = Days.Default.Time(I.tostring())
Would become:
AvailableDays[i] = Days.Default.Time[I];
Reflection is always an option too and i have an example below that is in a Windows Console Application:
public class Default
{
public int Time1 { get; set; }
public int Time2 { get; set; }
public int Time3 { get; set; }
}
class Program
{
static void Main(string[] args)
{
Default d = new Default();
Type t = d.GetType();
foreach (var info in t.GetProperties())
{
//SET VALUE
info.SetValue(d, 1);
}
foreach (var info in t.GetProperties())
{
//GET VALUE
Console.WriteLine("Property: {0}", info.Name);
Console.WriteLine("Value: {0}", info.GetValue(d));
}
//OR JUST ONE PROPERTY
Console.WriteLine("Time1 Property Value: {0}", t.GetProperty("Time1").GetValue(d));
Console.ReadLine();//PAUSE THE CONSOLE AFTER PROCESSING
}
}
In your example using reflection:
Days.Default.GetType().GetProperty("Time" + I.ToString()).GetValue(Days.Default) as DayOfWeek;
Another option could be to use Reflection. And getting the values from the enum on the fly.
See the link: How to Get Enum Values with Reflection in C#
However, using a Dictionary<string, DayOfWeek> will give you better performance and more readable code.
I think you could better resolve your problem by implementing your configuration using a
ConfigurationElementCollection. Then the 'names' of the configuration elements are irrelevant. You enumerate a collection of values and use those directly.
See here for an example; How to implement a ConfigurationSection with a ConfigurationElementCollection.

Global validation of input in a C#/.NET environment?

I'm still quite new to C#, I know this is pretty easy in VBA (my "preferred" language). I have a bunch of data input objects (text/numbers/dates) and I want to be able to validate that the input is logical for the field. I don't want dates entered where text should be, I don't want integers entered where dates should be, etc...
I found this code that checks to see if a date entered is a valid date. However, I'm confused as to where in a C#/.NET app this function should go, and I'm confused as to how to call the function from one of my pages. Any help is appreciated. At the moment I have it in Site.Master.cs, which sounded like the proper place to be. I should state that I'd like to be able to put this validation in one place, as opposed to putting it on every form, because I've got 10 forms that have data entry controls on them.
static bool IsValidSqlDateTimeNative(string someval)
{
bool valid = false;
DateTime testDate = DateTime.MinValue;
System.Data.SqlTypes.SqlDateTime sdt;
if (DateTime.TryParse(someval, out testDate))
{
try
{
// take advantage of the native conversion
sdt = new System.Data.SqlTypes.SqlDateTime(testDate);
valid = true;
}
catch (System.Data.SqlTypes.SqlTypeException ex)
{
// no need to do anything, this is the expected out of range error
}
}
return valid;
}
Why don't you add a new class and have this as a static method so you can call it from anywhere in your application?
For example:
public static class DateTimeHelpers
{
static bool IsValidSqlDateTimeNative(string someval)
{
bool valid = false;
DateTime testDate = DateTime.MinValue;
System.Data.SqlTypes.SqlDateTime sdt;
if (DateTime.TryParse(someval, out testDate))
{
try
{
// take advantage of the native conversion
sdt = new System.Data.SqlTypes.SqlDateTime(testDate);
valid = true;
}
catch (System.Data.SqlTypes.SqlTypeException ex)
{
// no need to do anything, this is the expected out of range error
}
}
return valid;
}
}
Then call from anywhere in the application like this:
bool result = DateTimeHelpers.IsValidSqlDateTimeNative(mystring);
public static class Validation
{
public static bool IsValidSqlDateTimeNative(string someval)
{
DateTime testDate;
return DateTime.TryParse(someval, out testDate) &&
testDate >= SqlDateTime.MinValue.Value;
}
}
Usage:
var isValidSqlDate = Validation.IsValidSqlDateTimeNative("1200-01-01");
Also worth mentioning is that you can use datatype DateTime2 in the database which has a larger date range (same as the .net DateTime type) and a larger fractional precision.
A big difference between creating web-pages in .NET versus most scripting languages is that everything is generally compiled together into one big (fat) binary. This is generally the equivalent of having a single include.<lang> that includes everything, and then include that into your page. What this means in practice, is that you in C#/.NET normally create classes that are .cs files (ie. not in pages/master-files), and you simply call the functions/classes defined in said files from your pages/masters-files.
Also, as of C#'s object-oriented structure, you can't just create functions in the global namespace (or any namespace for that matter), you have to create a class, and then have your function live inside said class.

Categories

Resources