Omer van Kloeten's .NET Zen

Programming is life, the rest is mere details

News

Note: This blog has moved to omervk.wordpress.com.

Omer van Kloeten's Facebook profile

Omer has been professionally developing applications over the past 8 years, both at the IDF’s IT corps and later at the Sela Technology Center, but has had the programming bug ever since he can remember himself.
As a senior developer at NuConomy, a leading web analytics and advertising startup, he leads a wide range of technologies for its flagship products.

Get Firefox


powered by Dapper 

.NET Resources

Articles :: CodeDom

Articles :: nGineer

Culture

Projects

December 2008 - Posts

Adobe AIR and Hebrew Fonts

Twhirl(I’ve noticed quite a few people were having this problem, so I decided to blog about it. This might have to do with all non-English fonts, but I experienced it only with Hebrew)

TweetDeck

The only reason I use Adobe AIR is for the Twitter application Twhirl. However, I noticed the Hebrew text was incorrectly displayed (word order was reversed).

I did not find a solution for this online and the guys at Twhirl didn’t know what to make of this.

After toying with a few of the options, I finally found the answer – the fonts used by Twhirl were in Hebrew, but AIR wasn’t playing nicely with them. I switched from Calibri to Tahoma and found that the text was just fine.

Both @effifuks and @JonathanRauch (with TweetDeck, where he didn’t see Hebrew text at all – see the left screenshot) experienced the same issue.

MSBuild Script to Compress All JavaScript Files in a Project
I’ve got one project in my solution which has a lot of JavaScript files and they keep on coming. We’ve been using the YUI Compressor for quite a while and it’s proven an effective tool. After a lot of time of fiddling with the project’s MSBuild script, I came up with the following:
<Target Name="BeforeBuild">
  <MakeDir
Directories="compressed\%(Content.RelativeDir)"
Condition="(%(Content.Extension) == '.js') And (!(Exists('compressed\%(Content.RelativeDir)')))" /> <Exec
Command="java -jar yuicompressor-x.y.z.jar --type js -o compressed\%(Content.Identity) %(Content.Identity)"
Condition="%(Content.Extension) == '.js'" /> <CreateItem
Include="compressed\%(Content.Identity)"
Condition="%(Content.Extension) == '.js'" /> </Target>

The above takes all of the JavaScript files in your project, compresses them (in the same relative directories) into the compressed directory and then adds them to the project, in case it gets deployed anywhere.

Note that I’m using the Extension, Identity and RelativeDir well-known item metadata attributes in order to impose batching, since batches causes loops instead of the string concatenation that happens when you reference the items themselves.

Your Mouth Says Windows-1255, But Your Eyes Say ISO-8859-1

I recently wrote an engine that gets XML files stored at our clients’ servers using HTTP requests. One of our clients decided to serve the XML file with one encoding and encode the file itself with another. This posed a problem to XDocument.

The client decided to encode their XML using the Windows-1255 encoding (Hebrew), noting the encoding correctly in the XML’s declaration, but served the file stating the ISO-8859-1 (Latin) encoding. This meant that I couldn’t just use XDocument’s normal Load method to load directly from the stream because XDocument looks at the HTTP headers and takes the document’s encoding from them.

Here’s a snippet of the code I used to get over that:

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    // Use response's charset.
    var encoding = Encoding.GetEncoding("ISO-8859-1");

    if (!string.IsNullOrEmpty(response.CharacterSet))
        encoding = Encoding.GetEncoding(response.CharacterSet);

    byte[] bytes = ReadStream(response.GetResponseStream());

    // Get the XML with the response's charset.
    string xml = new string(encoding.GetChars(bytes));
    int endOfDeclaration = xml.IndexOf("?>");

    if (endOfDeclaration != -1)
    {
        // Try to find out the encoding from the declaration.
        string decl = xml.Substring(0, endOfDeclaration + 2) + "<duperoot />";
        XDocument declDoc = XDocument.Parse(decl);
        var docEncoding = Encoding.GetEncoding(declDoc.Declaration.Encoding);

        if (docEncoding == encoding)
            return xml;
        else
            return new string(docEncoding.GetChars(bytes));
    }
    else
    {
        // Not XML or something... Send up.
    }
}

What I did here was to create a new document with the original XML’s declaration (the Latin characters which make up the XML’s declaration always have the same byte position), add a dupe root and parse that to get the name of the encoding used by the document. I then use that encoding to decode the document correctly.

Note that I’m using ISO-8859-1 as the default response’s encoding, since that is what HTTP’s specification demands.

HTML to JavaScript HTML DOM Converter

One of our products demands converting quite a large amount of HTML to equivalent scripts, written in JavaScript that create said HTML. Looking around the Internet, I found no tool that will automate this process for me, so I went ahead and created this simple little application.

htmltojsdom

I've written it using HTML Agility Pack and Simple CSS Parser. It’s hardly perfect and might incorrectly reference attributes, but I’ve tweaked it long enough for it to work, I’m guessing, 95% of the time.

The source is not yet included (I want to set it up as a project on CodePlex later on), but for now you can download it from here.

The Death of System.DateTime?

It’s been a few months since I started getting acquainted with the System.DateTimeOffset type and I can honestly say I don’t see any reason to use System.DateTime anymore.

I’ve even gone as far as ask whether anyone knew when I would rather use DateTime over DateTimeOffset. The responses I got were along the lines of ‘backwards compatibility’ or ‘when you need an abstract time’. My recommendation is that if you haven’t yet looked at the type, go do it now and after that, start using it.

So what is this DateTimeOffset? When representing a date/time, especially in an internationally-faced system, you have to include a time-zone. DateTime did a very poor job handling time-zones, like being insensitive to changes. DateTimeOffset is the exact same thing as DateTime, only it takes heed of time-zones. For instance, comparing two DateTimeOffsets with the same UTC time in different time-zones will result in equality.
Moreover, DateTime also had only three modes: Local, UTC and Unspecified, whereas DateTimeOffset has an Offset property, allowing you to create dates in any time-zone you like.

Things to note:

  1. DateTime can be implicitly converted to DateTimeOffset, but not vice-versa. To do that, you would have to use DateTimeOffset’s DateTime property.
    When converting this way, the DateTime’s kind will always be Unspecified.
    DateTimeOffset dateTimeOffset = DateTimeOffset.UtcNow;
    DateTime dateTime = dateTimeOffset.DateTime;
  2. When parsing a DateTimeOffset, note that you can specify AssumeUniversal and AssumeLocal using the DateTimeStyles enum. These come in handy when the string you’re parsing has no time-zone data.
    if (!DateTimeOffset.TryParse(myDateString, CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal, out dateTimeOffset))
        dateTimeOffset = default(DateTimeOffset);
  3. It is a best practice to store all of your dates as UTC in the database, regardless of the physical location of your users / servers. When doing this, be sure to manually change your DateTimeOffset objects to UTC using ToUniversalTime and only then use the DateTime property as I have previously noted.
    SaveTimeToDatabase(dateTimeOffset.ToUniversalTime().DateTime);
    Note that you do not need to convert DateTimeOffset objects to any time-zone to do calculations / comparisons. The only time you need to convert them to a time-zone is for displaying them to the user.
  4. If you want to store a user’s time-zone (on a database that doesn’t support date/times with time-zones), it would be best to have a translation table and use the TimeZoneInfo class’s Ids (for instance: TimeZoneInfo.Local.Id). Then you could use TimeZoneInfo.FindSystemTimeZoneById to translate that value to a TimeZoneInfo and use that object’s BaseUtcOffset property to get the difference from UTC.
    This may seem a bit cumbersome, but considering the fact that time-zones change due to daylight savings time, you can’t just store the difference from UTC and would be better suited allowing Windows to take care of these issues for you.
    Here’s a sample of this method of conversion:
    string id = "Israel Standard Time";
    DateTimeOffset utcnow = DateTimeOffset.UtcNow;
    
    DateTimeOffset now = utcnow.ToOffset(TimeZoneInfo.FindSystemTimeZoneById(id).BaseUtcOffset);

Side note: When storing these in the database, it would be prudent to use SQL Server 2008’s datetimeoffset type, which is the equivalent of DateTimeOffset and takes care of the time-zones in the same manner.

More Posts