date code and string reverse

  • Thread starter Thread starter Dan Holmes
  • Start date Start date
D

Dan Holmes

I have a need to reverse a date to show as a "date code". For example
today, 090507 would be coded as 905070 (reversing the parts of the date.

This is what i have but there has to be a better way.

DateTime d = DateTime.Now;
string datecodemonth = d.ToString("MM");
datecodemonth = datecodemonth[1] + datecodemonth[0];
string datecodeday = d.ToString("dd");
datecodeday = datecodeday[1] + datecodeday[0];
string datecodeyear = d.ToString("yy");
datecodeyear = datecodeyear[1] + datecodeyear[0];
string datecode = datecodemonth + datecodeday + datecodeyear;

Ideas? Is there anything in the format of the date that will do this?

dan
 
Seems a very odd thing to want to do, but why not ;-p
If this is high volume, then to avoid lots of intermediate strings,
try to work in a char[] buffer, something like:

static void Main(string[] args) {
char[] buffer =
DateTime.Today.ToString("MMddyy").ToCharArray();
Swap(buffer, 0, 1); // perhaps unroll...
Swap(buffer, 2, 3);
Swap(buffer, 4, 5);
string s = new string(buffer);
Debug.WriteLine(s);
}
static void Swap(char[] data, int index1, int index2) {
char c = data[index1];
data[index1] = data[index2];
data[index2] = c;
}
 
Ideas? Is there anything in the format of the date that will do this?

Firstly, create a function to reverse a string:

string StringReverse(string pstrString)
{
char[] strArray = pstrString.ToCharArray();
Array.Reverse(strArray);
return new string(strArray);
}

Then do the following:

string strDateLiteral = "090507";
DateTime dtmDate = DateTime.ParseExact(strDateLiteral, "MMddyy", null);
string strDateReversed =
StringReverse(dtmDate.ToString("MM")) +
StringReverse(dtmDate.ToString("dd")) +
StringReverse(dtmDate.ToString("yy"));
 
I have a need to reverse a date to show as a "date code". For example
today, 090507 would be coded as 905070 (reversing the parts of the date.

Both Mark's and Marc's examples use the default DateTime string format
provider, and then manipulates its results. A more .NET-ty solution
might be to implement a custom format provider, and use that to create
a string from a DateTime instead of the default provider. This would
avoid first going to 090507 and then to 905070, going directly to
905070 from a DateTime instance. See here for an example on how to
implement a custom format provider: http://www.codeproject.com/csharp/custstrformat.asp
 
Dan said:
I have a need to reverse a date to show as a "date code". For example
today, 090507 would be coded as 905070 (reversing the parts of the date.

This is what i have but there has to be a better way.

DateTime d = DateTime.Now;
string datecodemonth = d.ToString("MM");
datecodemonth = datecodemonth[1] + datecodemonth[0];
string datecodeday = d.ToString("dd");
datecodeday = datecodeday[1] + datecodeday[0];
string datecodeyear = d.ToString("yy");
datecodeyear = datecodeyear[1] + datecodeyear[0];
string datecode = datecodemonth + datecodeday + datecodeyear;

Ideas? Is there anything in the format of the date that will do this?

You can do this with string operations or perhaps with a custom format
provider. I would however go for a numeric method, as the source is numeric.

Something like:

DateTime d = DateTime.Now;
int year = d.Year % 100;
int month = d.Month;
int day = d.Day;
string dateCode =
(month % 10).ToString() +
(month / 10).ToString() +
(day % 10).ToString() +
(day / 10).ToString() +
(year % 10).ToString() +
(year / 10).ToString();
 
Göran Andersson said:
Dan said:
I have a need to reverse a date to show as a "date code". For example
today, 090507 would be coded as 905070 (reversing the parts of the date.

This is what i have but there has to be a better way.

DateTime d = DateTime.Now;
string datecodemonth = d.ToString("MM");
datecodemonth = datecodemonth[1] + datecodemonth[0];
string datecodeday = d.ToString("dd");
datecodeday = datecodeday[1] + datecodeday[0];
string datecodeyear = d.ToString("yy");
datecodeyear = datecodeyear[1] + datecodeyear[0];
string datecode = datecodemonth + datecodeday + datecodeyear;

Ideas? Is there anything in the format of the date that will do this?

You can do this with string operations or perhaps with a custom format
provider. I would however go for a numeric method, as the source is
numeric.

Something like:

DateTime d = DateTime.Now;
int year = d.Year % 100;
int month = d.Month;
int day = d.Day;
string dateCode =
(month % 10).ToString() +
(month / 10).ToString() +
(day % 10).ToString() +
(day / 10).ToString() +
(year % 10).ToString() +
(year / 10).ToString();


StringBuilder people...StringBuilder!!!

--
Doug Semler, MCPD
a.a. #705, BAAWA. EAC Guardian of the Horn of the IPU (pbuhh).
The answer is 42; DNRC o-
Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira
erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?
 
StringBuilder people...StringBuilder!!!

why? StringBuilder is useful when concatenating an /unknown/ quantity
of items (especially in a loop); In examples such as Göran's, this
will be interpreted by the compiler as string.Concat((month %
10).ToString(), ... , (year / 10).ToString()), which is both simpler
and more performant (it pre-allocates the correct size string, then
backfills [mutating]) than StringBuilder. Likewise, the char[] buffer
approach is perfectly performant and simple. Why over-complicate
things?

Don't get me wrong - StringBuilder has its place, but I'm not sure
that this is it...

Marc
 
Doug said:
Göran Andersson said:
Dan said:
I have a need to reverse a date to show as a "date code". For
example today, 090507 would be coded as 905070 (reversing the parts
of the date.

This is what i have but there has to be a better way.

DateTime d = DateTime.Now;
string datecodemonth = d.ToString("MM");
datecodemonth = datecodemonth[1] + datecodemonth[0];
string datecodeday = d.ToString("dd");
datecodeday = datecodeday[1] + datecodeday[0];
string datecodeyear = d.ToString("yy");
datecodeyear = datecodeyear[1] + datecodeyear[0];
string datecode = datecodemonth + datecodeday + datecodeyear;

Ideas? Is there anything in the format of the date that will do this?

You can do this with string operations or perhaps with a custom format
provider. I would however go for a numeric method, as the source is
numeric.

Something like:

DateTime d = DateTime.Now;
int year = d.Year % 100;
int month = d.Month;
int day = d.Day;
string dateCode =
(month % 10).ToString() +
(month / 10).ToString() +
(day % 10).ToString() +
(day / 10).ToString() +
(year % 10).ToString() +
(year / 10).ToString();


StringBuilder people...StringBuilder!!!

Why? A StringBuilder doesn't perform better, and there is no scalability
issues here.

If you want performance, this is four times faster:

DateTime d = DateTime.Now;
int year = d.Year % 100;
int month = d.Month;
int day = d.Day;
char[] c = new char[6];
c[0] = (char)((month % 10) + 48);
c[1] = (char)((month / 10) + 48);
c[2] = (char)((day % 10) + 48);
c[3] = (char)((day / 10) + 48);
c[4] = (char)((year % 10) + 48);
c[5] = (char)((year / 10) + 48);
return new string(c);
 
Doug said:
Göran Andersson said:
Dan Holmes wrote:
I have a need to reverse a date to show as a "date code". For
example today, 090507 would be coded as 905070 (reversing the parts
of the date.
This is what i have but there has to be a better way.
DateTime d = DateTime.Now;
string datecodemonth = d.ToString("MM");
datecodemonth = datecodemonth[1] + datecodemonth[0];
string datecodeday = d.ToString("dd");
datecodeday = datecodeday[1] + datecodeday[0];
string datecodeyear = d.ToString("yy");
datecodeyear = datecodeyear[1] + datecodeyear[0];
string datecode = datecodemonth + datecodeday + datecodeyear;
Ideas? Is there anything in the format of the date that will do this?
You can do this with string operations or perhaps with a custom format
provider. I would however go for a numeric method, as the source is
numeric.
Something like:
DateTime d = DateTime.Now;
int year = d.Year % 100;
int month = d.Month;
int day = d.Day;
string dateCode =
(month % 10).ToString() +
(month / 10).ToString() +
(day % 10).ToString() +
(day / 10).ToString() +
(year % 10).ToString() +
(year / 10).ToString();
StringBuilder people...StringBuilder!!!

Why? A StringBuilder doesn't perform better, and there is no scalability
issues here.

If you want performance, this is four times faster:

DateTime d = DateTime.Now;
int year = d.Year % 100;
int month = d.Month;
int day = d.Day;
char[] c = new char[6];
c[0] = (char)((month % 10) + 48);
c[1] = (char)((month / 10) + 48);
c[2] = (char)((day % 10) + 48);
c[3] = (char)((day / 10) + 48);
c[4] = (char)((year % 10) + 48);
c[5] = (char)((year / 10) + 48);
return new string(c);

It only comes out 2.3 times faster for me, but there we go. This
version is between the two, and I prefer it for readability:

DateTime d = DateTime.Now;
string original = d.ToString("yyddMM");
char[] c = original.ToCharArray();
Array.Reverse(c);
return new string(c);

Jon
 
StringBuilder people...StringBuilder!!!

why? StringBuilder is useful when concatenating an /unknown/ quantity
of items (especially in a loop); In examples such as Göran's, this
will be interpreted by the compiler as string.Concat((month %
10).ToString(), ... , (year / 10).ToString()), which is both simpler
and more performant (it pre-allocates the correct size string, then
backfills [mutating]) than StringBuilder. Likewise, the char[] buffer
approach is perfectly performant and simple. Why over-complicate
things?

Don't get me wrong - StringBuilder has its place, but I'm not sure
that this is it...

Marc

Sorry....bad joke...someone at work wants us all to change our string
concats to stringbuilders (there should have been a :^D at the end of
it hehe)
 
Doug said:
StringBuilder people...StringBuilder!!!
why? StringBuilder is useful when concatenating an /unknown/ quantity
of items (especially in a loop); In examples such as Göran's, this
will be interpreted by the compiler as string.Concat((month %
10).ToString(), ... , (year / 10).ToString()), which is both simpler
and more performant (it pre-allocates the correct size string, then
backfills [mutating]) than StringBuilder. Likewise, the char[] buffer
approach is perfectly performant and simple. Why over-complicate
things?

Don't get me wrong - StringBuilder has its place, but I'm not sure
that this is it...

Sorry....bad joke...someone at work wants us all to change our string
concats to stringbuilders (there should have been a :^D at the end of
it hehe)
Marc and Doug, is there expert opinion (yourselves included of course!)
on when to use String and when to use StringBuilder? I started using
StrinbBuilder for some things then found that I was doing multiple
conversions to manipulate them - SB to S, do something with S, convert
back to SB and vice versa....

Cheers,

Cliff
 
Enkidu said:
Doug said:
StringBuilder people...StringBuilder!!!
why? StringBuilder is useful when concatenating an /unknown/ quantity
of items (especially in a loop); In examples such as Göran's, this
will be interpreted by the compiler as string.Concat((month %
10).ToString(), ... , (year / 10).ToString()), which is both simpler
and more performant (it pre-allocates the correct size string, then
backfills [mutating]) than StringBuilder. Likewise, the char[] buffer
approach is perfectly performant and simple. Why over-complicate
things?

Don't get me wrong - StringBuilder has its place, but I'm not sure
that this is it...

Sorry....bad joke...someone at work wants us all to change our string
concats to stringbuilders (there should have been a :^D at the end of
it hehe)
Marc and Doug, is there expert opinion (yourselves included of course!) on
when to use String and when to use StringBuilder? I started using
StrinbBuilder for some things then found that I was doing multiple
conversions to manipulate them - SB to S, do something with S, convert
back to SB and vice versa....


The answer is:
It depends <big big grin>

A string, once instantiated, is immutable (cannot be changed). That means
that whenever you do a string manipulation function (substring, etc), you
are actually creating a new string. That being said:

The compiler, in cases such as the one above, can optimize alot of the
instantiations out of the picture that you wouldn't see. This is because,
even though a string is treated as an Object, at runtime it is treated as a
Value class (struct). Therefore, the compiler can actually perform compile
time value optimizations on strings. A simple example:

string MyFunc(int a, int b)
{
string sa = a.ToString();
string sb = b.ToString();
return sa + sb;
}

The compiler is smart enough to convert that into a concatination that is
back filled (basically what happens is an array of strings is created with
all of the "ToString" calls, on FINAL string is created, and the characters
of each string are then filled into the final string).

But....This can only happen with compile time optimizations. There are
certain situations (as mentioned earlier) in which a StringBuilder would be
useful. Probably one of the most useful situations is going to be NOT when
you are concatinating strings, but when you need to conditionally modify
portions of the final string.

Regardless of MSDN's "suggestions" about performance of String.* functions
versus StringBuilder, I usually use the most readable (or convenient, when
it comes to P/Invoke or COM)...To tell you the truth, in the programming
that I do, string building is the LEAST of my performance problems....It's
pointless to try to make up for a .04 millisecond delay in a function that
takes an overall of 10 milliseconds due to memory read alignment problems...

--
Doug Semler, MCPD
a.a. #705, BAAWA. EAC Guardian of the Horn of the IPU (pbuhh).
The answer is 42; DNRC o-
Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira
erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?
 
Doug Semler said:
The compiler, in cases such as the one above, can optimize alot of the
instantiations out of the picture that you wouldn't see. This is because,
even though a string is treated as an Object, at runtime it is treated as a
Value class (struct).

No, it is certainly *not* treated as a struct. It's treated as a
reference type in every possible way.
Therefore, the compiler can actually perform compile
time value optimizations on strings. A simple example:

string MyFunc(int a, int b)
{
string sa = a.ToString();
string sb = b.ToString();
return sa + sb;
}

The compiler is smart enough to convert that into a concatination that is
back filled (basically what happens is an array of strings is created with
all of the "ToString" calls, on FINAL string is created, and the characters
of each string are then filled into the final string).

Um, any evidence of that?

I believe that 3 completely separate strings will be created in the
above code. There's no special optimisation going on as far as I'm
aware.
 
Um, any evidence of that?
I agree with Jon; the real demonstration here is when you have more
than 2 strings:

string d = a + b + c; // 3 existing strings

The point is, it /doesn't/ evaluate the left-to-right, which is what
you might reasonably expect, but which would create intermediate
strings (i.e. tmp = a+b, d = tmp + c). Instead the complier swaps it
for:

string d = string.Concat(a,b,c);

Internally, string.Concat finds the sum of all the strings, allocates
a buffer big enough for all 3, and inserts the provided strings into
the buffer one after the other. Generally, you would have to use a
char[] buffer for this, but since the new string hasn't seen the
outside world yet, the runtime actually uses a string directly and
edits the (otherwise immutable) string directly.

Marc
 
is there expert opinion (yourselves included of course!) on when
to use String and when to use StringBuilder?

Jon's page is (as usual) quite illuminating:
http://www.pobox.com/~skeet/csharp/stringbuilder.html

Basically, if you are concatenating strings in a loop, then
StringBuilder is your friend. If you are concatenating strings in a
single line (i.e. someVar + "alkfj" + someOtherVar + whatever + "
items"), then just let the compiler do the work. You can also use
StringBuilder to retain editability of the contents while
concatenating, but I've never had to use this (I prefer to simply
build the correct string as I go)).
If you are writing an über-string (perhaps file contents, CSV
maybe...) then a third approach is to use a TextWriter to write
directly to an output Stream (such as a file, or an HttpResponse).
This can be even more efficient, as the working data is minimised -
very useful for server work or volume processing.

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top