October 2011 - Posts

DateTime.ToString() gotcha

Atruna: Esmu nolēmis izmēģināt rakstīšanu divās valodās un kādu laiku publicēt ierakstus gan latviski, gan angliski. Šis ieraksts ir anglisks tulkojums rakstam “DateTime.ToString() nianse”.

Disclaimer: I have decided to try dual language blogging and for some time post in both Latvian and English. This is English translation of “DateTime.ToString() nianse”.

Recently I got bitten by an interesting gotcha in DateTime.ToString() templates. It turned out that the slash character “/” specifies the date separator which is replaced with localized value from current or specified culture.

To demonstrate we can use this test:

  1.         [TestMethod]
  2.         public void FailingTest()
  3.         {
  4.             var date = new DateTime(2011, 11, 11);
  5.             var expected = "2011/11/11";
  6.             var actual = date.ToString("yyyy/MM/dd");
  7.             Assert.AreEqual(expected, actual);
  8.         }

If your computers regional settings have set date separator, other than “/”, test should fail. Otherwise you can specify culture explicitly to reproduce same behaviour.

What to do if you need date separated with slashes? It’s simple, you just need to escape the slash with an apostrophes.

Following test will pass:

  1.         [TestMethod]
  2.         public void SucessfulTest()
  3.         {
  4.             var date = new DateTime(2011, 11, 11);
  5.             var expected = "2011/11/11";
  6.             var actual = date.ToString("yyyy'/'MM'/'dd");
  7.             Assert.AreEqual(expected, actual);
  8.         }

For “works on my machine” proof, there is screenshot:

image_thumb3

DateTime.ToString() nianse

Nupat saskāros ar interesantu niansi, saistītu ar DateTime.ToString() formāta šablonu. Izrādās, ka slīpsvītra “/”, patiesībā ir speciālais šablona simbols, kurš tiek aizvietots ar datuma atdalītājsimbolu no reģionālajiem iestatījumiem.

Lai to pārbaudītu, var izmantot šādu testu:

  1.         [TestMethod]
  2.         public void FailingTest()
  3.         {
  4.             var date = new DateTime(2011, 11, 11);
  5.             var expected = "2011/11/11";
  6.             var actual = date.ToString("yyyy/MM/dd");
  7.             Assert.AreEqual(expected, actual);
  8.         }

Ja datorā ir LV reģionālie iestatījumi, tad šim testam vajadzētu izgāzties.

Ko darīt, ja vajag datumu noformēt ar slīpsvītru, kā atdalītāju? Pavisam vienkārši, slīpsvītru iekļaut apostrofos.

Šāds tests jau būs veiksmīgs:

  1.         [TestMethod]
  2.         public void SucessfulTest()
  3.         {
  4.             var date = new DateTime(2011, 11, 11);
  5.             var expected = "2011/11/11";
  6.             var actual = date.ToString("yyyy'/'MM'/'dd");
  7.             Assert.AreEqual(expected, actual);
  8.         }

Un pierādījumam, ka “works on my machine”, attēls ar testa rezultātiem:

image

Konfigurācijas failu labošana ar PowerShell

Pāris dienas atpakaļ, automatizējot dažādus sīkumus, radās vajadzība pamainīt web.config failu no skripta. Konkrētāk, vajadzēja pamainīt datubāzes konfigurāciju, kura glabājas atsevišķā konfigurācijas sekcijā.

Atbilstošais web.config fragments ir apmēram šāds:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <configuration>
  3.     <connections>
  4.         <Main server="."
  5.               database="Main"
  6.               user="MainSite"
  7.               password="BEwTIDU">
  8.         </Main>
  9.         <Log server="."
  10.              database="Log"
  11.              user="AuditWriter"
  12.              password="TIDUaEAL1">
  13.         </Log>
  14.     </connections>
  15. </configuration>

Sportiskas intereses vadīts, nolēmu, ka šis varētu būt darbs, kuru lieliski varētu paveikt ar PowerShell. Pirmā doma bija to izdarīt ar regulārajām izteiksmēm. Nu, jūs jau ziniet…

Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.

Un tad man ienāca prātā doma, ka web.config taču ir tikai XML fails, kuru lieliski varētu arī kā tādu apstrādāt. Palaidu uzticamo PowerShell ISE un sāku eksperimentēt (t.i., meklēt internetā piemērus, ko pielāgot).

Gala rezultātā izrādījās, ka viss ģeniālais ir vienkāršs un recepte konfigurācijas faila labošanai ir pavisam vienkārša:

  1. Izveido XmlDocument instanci
  2. Ielasa failu
  3. Izmaina atbilstošā elementa vērtību
  4. Saglabā XmlDocument failā

Ja to uzraksta kā skriptu:

  1. param([string]$webConfig = '', [string]$server = '.\sql2008' )
  2. $xml = New-Object System.Xml.XmlDocument
  3. $xml.Load($webConfig)
  4. $doc = $xml.get_DocumentElement();
  5. $doc.connections.Main.server = $server
  6. $doc.connections.Log.server = $server
  7. $xml.Save($webConfig)

Visvairāk man šajā pieejā patīk tas, ka līdz atbilstošajam elementam var nokļūt izmantojot “strongly typed” sintaksi, kā tas ir redzams skripta 5. un 6. rindā.

Veiksmīgu skriptēšanu!