C# DateTime to String Issue - c#

I feel like this is something I've done a thousand times so not sure why it is being so difficult now. I've created a method that simply returns Today's date for the user based on their UTC offset. But instead of returning a string resembling a date, it is returning this garbage
"䙭/䙭/Ἰ뻱䙭"
Here is the code.
public string getToday(Context context)
{
var settings = PreferenceManager.GetDefaultSharedPreferences(context);
var offset = settings.GetInt("offset", -5);
var now = DateTime.UtcNow.AddHours(offset);
return now.ToShortDateString();
}
When I step into the code using a breakpoint, offset and now both seem correct. now contains valid date parts all appearing to be accurate. Something about converting now to a string seems to go horribly wrong. Also tried:
return now.ToString("MM/dd/yyyy");
Same result. Weird part is the below code in another activity works without issue
var offset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Hours;
var now = DateTime.UtcNow.AddHours(offset);
now.ToString("MM-dd-yyyy")

Sounds to me like a localization issue. Make sure you're actually in English, be it en-US or similar.

I assume that your device is set to a Chinese/Japanese/Korean culture. If you always want to return US dates, use:
return now.ToString("MM/dd/yyyy", CultureInfo.InvariantCulture);
Edit: Given the rest of your comments, I’m starting to suspect that this might be caused by corruption, or by a bug in the MonoDroid implementation. You could try working around it by constructing the date manually (although this admittedly doesn’t address the cause of your issue):
return string.Format("{0:00}/{1:00}/{2:0000}", now.Month, now.Day, now.Year);

Related

Changing windows culture programmatically in C#

I want to change the windows culture settings programmatically since when using my program I need to parse the dot "." as the decimal number and windows has by default set the ",". So I'm looking for this.
I already tried by changing the current app culture but when parsing data from db it still gets in trouble because it uses windows configuration.
I'll emphasize, do it better.
This can be pretty easily solved, and a quick example:
public static decimal GetInvariantDecimal(string internationDecimalString)
{
var looksUnAmerican = Regex.IsMatch(internationDecimalString, #"(\d+,\d{2}\b)|(\d+\.\d+,\d{0,2})|(\d+\.\d{3})");
Console.WriteLine(looksUnAmerican);
return looksUnAmerican ?
Decimal.Parse(internationDecimalString, NumberStyles.Currency, CultureInfo.GetCultureInfo("tr-TR")) :
Decimal.Parse(internationDecimalString, CultureInfo.InvariantCulture);
}
public static void Main()
{
var american = "123.55";
var international = "234,55";
Console.WriteLine(GetInvariantDecimal(american));
Console.WriteLine(GetInvariantDecimal(international));
}
It will give you a standard decimal for the correct environment, and you would use this every time you work with the string from the database. (of course, it doesn't currently handle something like "1,234.01"...
But output:
123.55
234.55
And one more bit, changing the users machines culture will likely cause all sorts of bugs in who knows what...

Set Expiring Date To .NET Output (Without Hardware Dongles)

My first solution for this problem is to use OS/BIOS timer and check it with encrypted date file ( see below pseudocode )
public void CheckFrequently()
{
DateTime registeredDate = ReadFromBiosOrOSTimer();
DateTime readEncryptedDate = ReadFromEncryptedFile();
if(registeredDate >= readEncryptedDate)
{
ShowExpireDateForm();
CloseProgram();
}
}
In this case its obvious that user could change OS/BIOS timer easily and my method not works.
my questions are :
Is there any way to fix user OS/BIOS timer change problem?
Is there any better way to set expiration date to .Net projects?
(My answer is assuming you want to have an "expiring" program of some sort.)
The end-all-be-all big brother answer would be to retrieve a trusted time from an external source, say, a web service. Of course, connectivity (or lack thereof) may make this impossible.
Other than that, knowing that if someone is going to cheat the clock, they would likely do it very close to the expiration, periodically write, somewhere, a timestamp of the current time. If you ever encounter a case where the retrieved (via system call) time is less than the last timestamp, someone might be trying to trick the clock and you can invalidate the session/instance with the appropriate error message. Once you've detected the "expired" case, it's simple to flip a switch and refuse to run anymore.
All of that said, a countermeasure like this will most likely always be beaten by an adversary who is determined enough.

Changing the value of a String in C# WinApp forever?

Assume I have a String Field in my WinApp like below :
public string UsingTheApplicationFrom =
"Not Yet";
Now , I wanna to change the value of the field forever, in first running of my application. e.g : UsingTheApplicationFrom = "‎Friday, ‎January ‎21, ‎2011";
Is it possible in C# WinApp ?
Could you please guide me?
Edit:
I don't wanna use Database or file or Registry or something else.
You are looking for "a type of security for my application that only the first system (that runs the application for the first time) could use my application". I think you mean that each copy of the software you sell may only be installed on one computer at a time.
You have two problems to solve:
How to generate a unique identifier for the computer
How to store the identifier value
You have several options to use for a unique identifier, none of which are great. Be prepared for support requests from customers when they change their computer hardware, when their computer breaks, or when they want to move the software from one computer to another. A decent-looking method to compute a unique identifier is this article (mirror link since the code project article is not available).
I would recommend just storing this identifier as a string in the app.config file (using Properties.Settings, start at this link for more information). It will be visible in plain text, but how would an unlicensed user know what value to change it to for their machine when it looks like "4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9"? If it doesn't match direct them to your website/telephone for support.
You still have the problem of deciding when to set this value -- I would advocate for setting it as part of an installer instead of saving it the first time the program is run, since then you still have a problem to determine when the program is first run. The installer might need some sort of registration code and a method to communicate with a central licensing server. (Yes, this does get complicated -- how determined do you think people might be to hack your licensing?)
I am taking a guess, but by "always" I think he means "forever". You could easily create a key in the App.config of your application and populate it on the first run.
<add key="UsingTheApplicationForm" value="Not Yet"/>
On first run, update it to -
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["UsingTheApplicationForm"].Value = DateTime.Now.ToShortDateString();
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
// Force a reload of a changed section.
ConfigurationManager.RefreshSection("appSettings");
On second run check if the key value is equal to "Not Yet". If it is not, it means that this is not the first run.
I think maybe you want to use DateTime, and particularly, DateTime.Now - as with comments to the question however, I'm not properly sure.
So, something like:
UsingTheApplicationForm = String.Format("{0:dddd, MMMM d, yyyy}", DateTime.Now);
The 'always' part is very confusing though, I'm just going to buy into my own translation, where always = each startup.
I would also conjecture that, given the property/variable name of UsingTheApplicationForm, this value is an indicative field, rather than a descriptive one; for this reason, may just using DateTime.Now without any formatting, or even just a boolean (depends what fits your situation) fit the bill?
Edit:
For information on using this method, or any of the others, along with persisting this data for the next run, see the following question and answers...
Editing app.config in execution time using the same App
I like this way:
http://windowsclient.net/blogs/suryahg/archive/2008/08/11/persist-winforms-application-settings.aspx
There's no way to do it with nothing more than a string object, but you can create a simple object that does it:
public class ApplicationInfo
{
private ApplicationStartTime()
{
this.StartTime = new DateTime().Now;
}
public DateTime StartTime
{
get; private set;
}
public Create()
{
return new ApplicationStartTime();
}
}
I haven't compiled that, so there may be a minor syntax error or two. You would invoke it like so:
var applicationInfo = ApplicationInfo.Create();
Debug.WriteLine(applicationInfo.StartTime.ToString());
In your program.cs or main entry point for the program declare a public static datetime.
when the program is first run you can set the date time and access it in future.
public static Datetime m_StartDate = DateTime.now;
public static void Main(args)
{
m_StartDate = DateTime.Now;
}
then in your other forms (assuming you added the code to Program.cs)
txtStartTime.Text = Program.m_StartDate.toString();

How does DateTime.Now.Ticks exactly work?

In my application I generate files at random opportunities. To ensure a unique naming, I tried to use the nano seconds since 1.1.1970:
long time = DateTime.Now.Ticks;
String fileName = Convert.ToString(time);
Console.WriteLine(fileName);
Now I observed something weird. Why is the output like that? I mean why are the last 4 numbers always the same? I can use this as a filename, that is not the problem, but I'm just wondering about it.
634292263478068039
634292263512888039
634292263541368039
634292263603448039
634292263680078039
The resolution of DateTime.Now depends on your system timer (~10ms on a current Windows OS)...so it's giving the same ending value there (it doesn't count any more finite than that).
Not really an answer to your question as asked, but thought I'd chip in about your general objective.
There already is a method to generate random file names in .NET.
See System.Path.GetTempFileName and GetRandomFileName.
Alternatively, it is a common practice to use a GUID to name random files.
You can get the milliseconds since 1/1/1970 using such code:
private static DateTime JanFirst1970 = new DateTime(1970, 1, 1);
public static long getTime()
{
return (long)((DateTime.Now.ToUniversalTime() - JanFirst1970).TotalMilliseconds + 0.5);
}
to convert the current datetime to file name to save files you can use
DateTime.Now.ToFileTime();
this should resolve your objective
I had a similar problem.
I would also look at this answer: Is there a high resolution (microsecond, nanosecond) DateTime object available for the CLR?.
About half-way down is an answer by "Robert P" with some extension functions I found useful.

How to make C# write English (non-localized) number format by default?

I'm using English Visual Studio 2008 on English Windows 7, but I'm based in the Netherlands. A lot of my programs need to read and write floating point numbers. Compared to English, the Dutch notation of numbers switches the meaning of dots and comma's (i.e. 1.001 in Dutch is a thousand and one, and 1,001 is 1 + 1/1000). I will never ever ever have to write (or read) numbers in Dutch format, but for some reason, every program I compile defaults to it, so every ToString() is wrong. This gets me every time. I know I can put this at the start of every thread:
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
Or replace every instance of ToString() with:
String.Format(CultureInfo.InvariantCulture, "{0:0.####},{1:0.####}", x)
But sometimes I just want to compile something to see how it works, and not make any changes. Also, I'm bound to forget about this sometimes. Is there no way to just tell C#, .NET and/or Visual Studio to just always make all my projects/programs use the English number format?
It's not a matter of compilation - it's a matter of what happens at execution time. Unless you explicitly specify a culture, the current culture (at execution time) will be used. There's no way of changing this behaviour that I'm aware of, which leaves you the options of:
Explicitly stating the culture to use
Explicitly changing the current culture
Note that even if you change the current culture of the current thread, that may not affect things like the thread pool. Personally I think it's better to always use the culture explicitly.
You could always write your own extension methods to (say) call the original version but passing in CultureInfo.InvariantCulture. For example:
public static string ToInvariantString(this IFormattable source, string format)
{
return source.Format(format, CultureInfo.InvariantCulture);
}
Getting that right everywhere could be a pain, admittedly... and to avoid boxing you'd actually want a slightly different signature:
public static string ToInvariantString<T>(this T source, string format)
where T : IFormattable
{
return source.Format(format, CultureInfo.InvariantCulture);
}
You can add a line that sets CurrentCulture to Program.cs in your project templates.
Try: Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

Categories