I am writing activities of a program in a log with timestamp attached to each line with the following format:
DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss FFF")
I was expecting the millisecond portion to always have 3 digits. However the following appears:
11/29/2013 18:53:14 96 - SessionKey-2rvun1agyw1svcexmqf5dejh-MAC.Master Page_Load - Begin
11/29/2013 18:53:14 975 - SessionKey-2rvun1agyw1svcexmqf5dejh-MAC.Master Page_Load - End
In the first one, why is the millisecond portion not 096?
From The "FFF" Custom Format Specifier
The "FFF" custom format specifier represents the three most
significant digits of the seconds fraction; that is, it represents the
milliseconds in a date and time value. However, trailing zeros or
three zero digits are not displayed.
EDIT: Ok, I think I figure out what's going on here. In original, OP's millisecond part is 960 not 096.
That's why it is working exactly how describes in MSDN page.
It's trailing 0 at the end of 960, it is not leading 0 in 096.
As a solution, you can use The "fff" Custom Format Specifier instead. It doesn't trail or leading zeros in my opinion. At least it doesn't write in MSDN page :)
EDIT2: I think people are confusing what is trailing zero and leading zero
From Wikipedia pages;
Trailing zero
In mathematics, trailing zeros are a sequence of 0s in
the decimal representation (or more generally, in any positional
representation) of a number, after which no other digits follow.
Leading zero
A leading zero is any 0 digit that leads a number string
in positional notation. For example, James Bond's famous identifier,
007, has two leading zeros.
Use:
"MM/dd/yyyy hh:mm:ss fff"
on my machine:
hh:mm:ss.fff leading zeros
hh:mm:ss.FFF NO leading zeros
sample code:
for (int i = 0; i < 2222; i++)
{
Console.WriteLine(DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss fff"));
}
string input;
input = Console.ReadLine();
Related
In C#, if I run this code, it prints out 05:
Console.WriteLine(DateTime.Now.ToString("MM"));
However, if I run this code, it prints out May 16:
Console.WriteLine(DateTime.Now.ToString("M"));
I'm looking for a date format that will print out 5. How do I format a single digit month? To be clear, it would be 1 digit for months 1 to 9, and 2 digits for months 10 to 12.
“%M" should work. See custom format strings
Some explanation:
The "M" can be part of a custom format string, where it means a "month number" in one or two digits
But on itself it can also be a standard format string meaning a "month day pattern" - as the OP found out.
To resolve this ambiguity you can add a space, which makes it a custom format string, but also adds a space to the resulting value. Or you can add a %.
Right now (May) a DateTime.Now.ToString("%M") results in "5".
Microsoft has some excellent documentation regarding how to format DateTime as string values over at https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
The parameter you're looking for is M which would make the method call DateTime.Now.ToString("M");.
Update:
However, as pointed ut by Hans Kesting, this could give unexpected results in some situations which can be avoided by using a % in combination with the M as described at https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings#UsingSingleSpecifiers
var date= DateTime.ParseExact("16-03-2022 1:30", "dd-MM-yyyy HH:mm", CultureInfo.InvariantCulture);
When I enter 16-03-2022 13:30, it does not give an error but when the parameter is 16-03-2022 1:30, I get an error, how can I solve it?
I feel like taking a risk to answer but..
Let's go step by step. One of the good things about .NET methods is that you can see what exceptions can be thrown on that method in their documentation.
From "Exception" section on documentation it says;
FormatException
s or format is an empty string.
-or-
s does not contain a date and time that corresponds to the pattern
specified in format.
-or-
The hour component and the AM/PM designator in s do not agree.
Your s or format is not empty, your string does not have any AM or PM designator, so the only option left is "s does not contain a date and time that corresponds to the pattern specified in format." as a reason.
Also from documentation, it says;
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified format and culture-specific
format information. The format of the string representation must match
the specified format exactly.
What "format" we are talking about? There are two of them. Custom date and time format strings and Standard date and time format strings. Since we are using DateTime.ParseExact, we need to consider using custom date and time format.
Let's look at all parts can be parse in your 16-03-2022 1:30 string;
16 --> Two digit day number (dd)
03 --> Two digit month number with leading zero (MM)
2022 --> Four digit year (yyyy)
1 --> One digit hour (it can be h or H because there is no time designator in your string and we can't know it's in 12-hour clock format or 24-hour clock format)
30 --> Two digit minutes (mm)
So, the proper format of your 16-03-2022 1:30 string can be either dd-MM-yyyy H:mm or dd-MM-yyyy h:mm which depends on you. If it is 24-hour format, use H specifier, if it is 12-hour format, use h specifier.
When you see the word "Exact" in ParseExact(), it means it. Any deviation from the expected format at all will cause an exception.
In this case, the HH specifier is not an exact match for the 1 value for the hour. It would match if you had 01 instead, but just 1 isn't the same thing. To match the hours without leading zeros you need a single H, creating this format string:
dd-MM-yyyy H:mm
This will still match later hours like "10" and "11". Additionally, the capital "H" instead of lower-case means it still expects 24-hour time, so numbers like "13" up to "23" still work, too.
If you could get a mix of values, that sometimes has just the 1 and sometimes might have the full 01, then you need to use a ParseExact() overload that accepts an array of formats, and provide both versions.
I have a number between -12 and 12. How can I get it in this format: "+number:00"
Ex. for -4: -04:00
Ex. for 10: +10:00
That's more precise
number.ToString("+00;-00") + ":00"
-OR-
number.ToString("+00':00';-00':00'")
-4 --> -04:00
10 --> +10:00
If you just concerned about formatting the number to particular format with signs (positive/negative), you could
var positive = 5;
var negative = -12;
var strPositive = positive.ToString("+00':00';-0#':00'");
var strNegative = negative.ToString("+00':00';-0#':00'");
Output
+05:00
-12:00
You are making use of Conditional Formatting here. You can read more on the same here
Quoting.
The semicolon (;) is a conditional format specifier that applies
different formatting to a number depending on whether its value is
positive, negative, or zero
For a format string with two sections
The first section applies to positive values and zeros, and the second
section applies to negative values.
If the number to be formatted is negative, but becomes zero after
rounding according to the format in the second section, the resulting
zero is formatted according to the first section.
I want to be able to parse strings of time (hours, minutes, seconds) where the hours run from 0 to 23, and where the preceding zero for one-digit hours is optional.
Examples of time strings that I want to be able to parse into valid DateTime objects:
212540
061525
94505
I am trying to use the C# method DateTime.ParseExact to manage the parsing, but I cannot for the life of it come up with a format string that can handle the "single-digit hour without preceding zero" scenario.
How should I specify the DateTime.ParseExact format string to sufficiently parse all examples above with the same line of code?
Inspired by the MSDN page on custom date and time formats, I have tried the following approaches:
DateTime.ParseExact(time_string, "Hmmss", CultureInfo.InvariantCulture);
DateTime.ParseExact(time_string, "%Hmmss", CultureInfo.InvariantCulture);
DateTime.ParseExact(time_string, "HHmmss", CultureInfo.InvariantCulture);
All these format strings work for the first two example cases above, but faced with a single-digit hour and no preceding zero, all formulations throw a FormatException.
You can insert delimiters between hours, minutes and seconds like this:
string timeString = "94505";
string formatedTimeString = Regex.Replace(str, #"\d{1,2}(?=(\d{2})+$)", "$&:");
var datetime = DateTime.ParseExact(formatedTimeString, "H:mm:ss", CultureInfo.InvariantCulture);
UPDATE:
I've found the cause of failure when parsing "94505" with format string "Hmmss":
What's happening is that H, m and s actually grabs two digits when they can, even if there won't be enough digits for the rest of the format. So the for example with the format Hmm and the digits 123, H would grab 12 and there would only be a 3 left. And mm requires two digits, so it fails.
So basically you have two options for handling the "single-digit hour without preceding zero" scenario:
Change time format: place hours to the end (for example, "ssmmH" or "mmssH") or use delimiters (for example, "H:mm:ss")
Modify the string like I've suggested earlier or like keyboardP has.
You could pad your input string if you know that you'll always have six characters.
string input = "94505";
if(input.Length < 6)
input = input.PadLeft(6, '0');
(Or use input.Length == 5 if you have other valid formats that are shorter).
What about using:
DateTime.ParseExact(time_string, "Hmmss", CultureInfo.InvariantCulture).ToString("HH:mm:ss")
I want the DispatcherTimer to read time values from the textbox : objTextBox.
I tried this code however it seems that TimeSpan is not compatible with strings or did I do anything wrong?
Error: Argument 1: cannot convert from 'string' to 'long'
Also; Does the Time have to look like this in textbox: 0, 0, 1 or 00:00:01?
Code here:
private void testing()
{
string theText = objTextBox.Text;
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(listjob3_Tick);
dispatcherTimer.Interval = new TimeSpan(theText);
dispatcherTimer.Start();
}
To convert string to TimeSpan, use TimeSpan.Parse(str)
To convert to a TimeSpan from a string you could leverage TimeSpan.Parse, but you'd have to conform to this format [ws][-]{ d | [d.]hh:mm[:ss[.ff]] }[ws] where:
ws is Optional white space.
- is An optional minus sign, which indicates a negative TimeSpan.
d is Days, ranging from 0 to 10675199.
. is A culture-sensitive symbol that separates days from hours. The invariant format uses a period (".") character.
hh is Hours, ranging from 0 to 23.
: is The culture-sensitive time separator symbol. The invariant format uses a colon (":") character.
mm is Minutes, ranging from 0 to 59.
ss is Optional seconds, ranging from 0 to 59.
. is A culture-sensitive symbol that separates seconds from fractions of a second. The invariant format uses a period (".") character.
ff is Optional fractional seconds, consisting of one to seven decimal digits.
so just converting days you could in fact use TimeSpan.Parse and just pass in the string - but if you wanted to convert minutes it would take some massaging of the input like this:
var input = string.Format("00:{0}", objTextBox.Text.PadLeft(2, '0'));
and so then you could issue var timeSpan = TimeSpan.Parse(input); because you've formatted it properly and the Parse will succeed. Another option is to turn minutes into days I guess, but that would require some floating point work and is really, IMO, not as good of an option.
I'm guessing your exception is here:
dispatcherTimer.Interval = new TimeSpan(theText);
Use this instead:
dispatcherTimer.Interval = new TimeSpan(Convert.ToInt64(theText));
#Sneakybastardd: have you read the TimeSpan documentation regarding constructor overloads? You'll note that none of them take string arguments: integer types are required.
After reading the documentation, you might find these TimeSpan methods useful:
Parse()
ParseExact()
TryParse()
With respect to format, See "Standard TimeSpan Format Strings" and "Custom TimeSpan Format Strings". Also do a little research on the various default TimeSpan formats for different cultures if that comes into play at all.