How does DateTime.Now.Ticks exactly work? - c#

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.

Related

What is wrong with using DateTime.Now. as main part of Unique ID?

I used to use RNGCryptoServiceProvider to generate string-based Order ID's, but, there were 4 instances where ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%^*()_- would generate an already-existing Order ID.
And it got me thinking...
Why can't we just use something like:
<html>
...
<p>#GenerateOrderId()</p>
...
</html>
and:
public string GenerateOrderId()
{
return "OID" +
DateTime.Now.Year + DateTime.Now.Month +
DateTime.Now.Day +
DateTime.Now.Hour +
DateTime.Now.Minute +
DateTime.Now.Second +
DateTime.Now.Millisecond;
}
I've been told that it's a bad idea, but without any explanation, or reason, it's still stuck in my head.
... The reason I'd like to use this, is because it will always be unique.
Computers work at nanosecond speeds. You would be guaranteed to generate a duplicate order ID almost immediately.
Your best bet would be to use a GUID [MSDN-C#] [MSDN-SQL] (a.k.a. UNIQUEIDENTIFIER in the SQL world).
It won't always be unique.
If the same process is carried out during the same millisecond, then it will be identical.
As #Bill has stated, you should use a GUID for a unique string.
Never call the Now getter that many times. "Now" may change while you're adding the strings. You could say DateTime.Now.ToString("yyyyMMddHHmmssfff") or similar, but it's much better to use Guid.NewGuid() for this.
If you just want a globally unique identifier and aren't bothered about the format, why don't you just use a GUID?
http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx
using System;
class Sample
{
public static void Main()
{
Guid g = Guid.NewGuid();
Console.WriteLine(g);
}
}
It even has a type in T-SQL (which you may well be using given that you're using ASP.NET)
I recommend letting your database handle that responsibility, but if you must do it in code, then use GUID. GUID has a low probability of being duplicated.
public string GenerateOrderId()
{
return System.Guid.NewGuid().ToString();
}
Not to beat a dead horse, but your usage of DateTime.Now is of more concern than what you're trying to do. You can rewrite your method and achieve the same goal much more succinctly:
public string GenerateOrderID()
{
return "OID" + DateTime.Now.Ticks.ToString();
}
I would still recommend using a Guid over this approach. However, 99% of the time, the Ticks property is going to give you a different number each time it's called.

C# DateTime to String Issue

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);

How to format the Timestamp data when using TraceOptions.Timestamp

How can I format the Timestamp data that is printed when you set the TraceOutputOptions = TraceOptions.Timestamp?
Im getting something like:
Timestamp=41329240725 (real value that was written on the output text file)
EDITED:
I want something like 10:22:34.32938. How shoud I configure the TextWriterTraceListener to achieve that?
Do you really want to log the time that the message was written? If so, you want to use TraceOptions.DateTime. Note, that according to MSDN, the time is written as UTC.
If you want more control over the format of the time (including if you want it to be expressed in something other than UTC), then you will probably have write your own custom TraceListener, or find one that will do what you want.
One useful add on for System.Diagnostics is Ukadc.Diagnostics. With it you can easily add custom formatting to your log messages (similar to what you can do with log4net and NLog).
Here are some other links to answers that I have provided in the past to logging questions that you might find useful:
When should I use Tracing vs Logger.NET, Enterprise Library, log4net or Ukadc.Diagnostics?
When do I need more than one TraceSource in code?
According to this page
http://msdn.microsoft.com/en-us/library/a10k7w6c.aspx
TraceOptions Timestamp returns the number of ticks, so to convert ticks into time you need to do:
DateTime date = new DateTime(41329240725);
string FormattedDate = date.ToShortDateString();
however 41329240725, seems a little small for ticks (I'm hoping that was just an example)

how to afix this hhmmss problem

I was doing window services where I'm generating txt files in target path based on some details from a database but I have a problem the service is running too fast!
I was getting same file name in the place of sec variation required so that i can avoid duplicates over there.
code :
using (transactionscope scope = new transactionscope )
{
string nowtime = datetime.now.today.tostring(HHMMss) // it was working fine
}
file should be generates by specific file naming convention !! ex:hhmmss >>> no millisecond
can any one give me exclusive ideas how to face this part?
You can add milliseconds to the filename:
string nowtime = datetime.Now.Today.ToString("HHmmssfff");
See Custom Date and Time Format Strings.
A few notes about the code you posted:
MM is for months, not minutes. You should use lower case mm.
The parameter that ToString takes is a string.
Your code wouldn't compile as it is not correctly cased. Please use code that can be directly used in the future.
Update:
Seeing as you have to use this format, the only other choice is to "slow down" the service.
Adding a:
Thread.Wait(1000);
In the right place (end of loop?) could do the trick.
Alternatively, you can change your code to append to a file if you are still within the same second.
If you are saying that you are creating multiple files with the same name (multiple files in the same second), then I would take the time out to the milliseconds. You can do this with:
DateTime.Today.ToString("HHmmssfff");
The fff denotes the three places to the right of the decimal (thousandths of a second).

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();

Categories