<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html">Calendars - SeeSharp</title>
  <icon>http://www.hightech.ir/favicon.ico</icon>
  <logo>http://www.hightech.ir/favicon.png</logo>
  <updated>2009-04-26T15:57:00</updated>
  <subtitle type="html">A C# development blog</subtitle>
  <id>http://www.hightech.ir/tags/calendars/atom</id>
  <link rel="alternate" type="text/html" hreflang="en" href="/tags/calendars/atom"/>
  <link rel="self" type="application/atom+xml" href="http://www.hightech.ir/Tags/Calendars/ATOM"/>
  <generator uri="http://oxite.net" version="1.0">Oxite</generator>
  <entry>
    <title type="html">Dynamically Generated Images with ASP.NET MVC</title>
    <link rel="alternate" type="text/html" href="http://www.hightech.ir/SeeSharp/dynamically-generated-images-with"/>
    <id>http://www.hightech.ir/SeeSharp/dynamically-generated-images-with</id>
    <updated>2009-10-18T13:39:47.257</updated>
    <published>2009-04-26T15:57:00</published>
    <author>
      <name>HEskandari</name>
    </author>
    <category term="ASPNETMVC" />
    <category term="FarsiLibrary" />
    <category term="Calendars" />
    <content type="html" xml:lang="en">
      &lt;p&gt;For a site I'm working on using ASP.NET MVC, I intended to place a Date badge beside the blog and news posts I'm writing. Since in ASP.NET MVC there's no notion of custom controls (well, at least not like in WebForms) you'll have to do this manually, but as it turned out it was pretty easy to do.&lt;/p&gt;

&lt;p&gt;What I needed to do was to convert a Date instance, e.g. 04.23.2009 to a user friendly calendar icon like this one:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/_Z5KTIfnfuNs/SfRPHgU55rI/AAAAAAAAAN0/Vh0wfwsvIow/s1600-h/CalendarIcon3.png&quot;&gt;&lt;img style=&quot;border-width: 0px; display: inline;&quot; title=&quot;CalendarIcon&quot; alt=&quot;CalendarIcon&quot; src=&quot;http://lh5.ggpht.com/_Z5KTIfnfuNs/SfRPJsWuV5I/AAAAAAAAAN4/LFz8ONgu5ko/CalendarIcon_thumb1.png?imgmax=800&quot; width=&quot;46&quot; border=&quot;0&quot; height=&quot;51&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've seen blogs and site using different icon for each day of the month or a similar trick to do this, but why not actually render it using Graphics API and a picture?&lt;/p&gt;

&lt;p&gt;The first step was to decide what should be returned in you Controller's action method, as the action result? Since there's nothing that returns an Image as the result, let's create one:&lt;/p&gt;

&lt;pre class=&quot;brush:c-sharp&quot;&gt;
public class ImageResult : ActionResult
{
  public Image Image
  {
      get; set;
  }

  public ImageFormat ImageFormat
  {
      get; set;
  }

  private static Dictionary&amp;lt;ImageFormat, string&amp;gt; FormatMap
  {
      get; set;
  }

  static ImageResult()
  {
      CreateContentTypeMap();
  }

  public override void ExecuteResult(ControllerContext context)
  {
      if (Image == null) throw new ArgumentNullException(&quot;Image&quot;);
      if (ImageFormat == null) throw new ArgumentNullException(&quot;ImageFormat&quot;);

      context.HttpContext.Response.Clear();
      context.HttpContext.Response.ContentType = FormatMap[ImageFormat];

      Image.Save(context.HttpContext.Response.OutputStream, ImageFormat);
  }

  private static void CreateContentTypeMap()
  {
      FormatMap = new Dictionary&amp;lt;ImageFormat, string&amp;gt;
      {
          { ImageFormat.Bmp,  &quot;image/bmp&quot;                },
          { ImageFormat.Gif,  &quot;image/gif&quot;                },
          { ImageFormat.Icon, &quot;image/vnd.microsoft.icon&quot; },
          { ImageFormat.Jpeg, &quot;image/Jpeg&quot;               },
          { ImageFormat.Png,  &quot;image/png&quot;                },
          { ImageFormat.Tiff, &quot;image/tiff&quot;               },
          { ImageFormat.Wmf,  &quot;image/wmf&quot;                }
      };
  }
}
&lt;/pre&gt;

Pretty easy, ha? You just need to specify the image and the format and it is rendered to the HttpContext as an image. The controller action to render the text would something like this:&lt;br /&gt;

&lt;pre class=&quot;brush:c-sharp&quot;&gt;
public ActionResult GetCalendarBadge(DateTime displayDate)
{
  Graphics graphics = ?;
  Bitmap bmp = ?;

  //Draw using graphics

  //Direct the output to the bitmap

  return new ImageResult { Image = bmp, ImageFormat = ImageFormat.Png };
}
&lt;/pre&gt;

...and on the view:&lt;br /&gt;

&lt;pre class=&quot;brush:c-sharp&quot;&gt;
&amp;lt;% foreach(var item in this.Model.News) %&amp;gt;
     &amp;lt;%= Html.Image&amp;lt;NewsController&amp;gt;(o =&amp;gt; o.GetCalendarBadge(item.DisplayDate), 100, 100) %&amp;gt;
&amp;lt;% } %&amp;gt;
&lt;/pre&gt;

&lt;br /&gt;
&lt;a href=&quot;http://lh6.ggpht.com/_Z5KTIfnfuNs/SfRPL2NGqZI/AAAAAAAAAN8/SLmInKZkrKA/s1600-h/Calendar%5B4%5D.png&quot;&gt;&lt;img style=&quot;border: 0px none ; margin: 0px 15px 0px 0px; display: inline;&quot; title=&quot;Calendar&quot; alt=&quot;Calendar&quot; src=&quot;http://lh6.ggpht.com/_Z5KTIfnfuNs/SfRPN0r2QLI/AAAAAAAAAOA/eN7vVPK8XTY/Calendar_thumb%5B2%5D.png?imgmax=800&quot; width=&quot;90&quot; align=&quot;left&quot; border=&quot;0&quot; height=&quot;83&quot; /&gt;&lt;/a&gt;Now, to make things easier, le's use an existing bitmap as our canvas and just draw the values on it. To do this, add an existing image to your project and load it. The rest is just GDI API that renders the date values according to user's Cultural setting.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;

&lt;pre class=&quot;brush:c-sharp&quot;&gt;
public ActionResult GetCalendarBadge(DateTime displayDate)
{
  var bmp = Images.Calendar;
  var g = Graphics.FromImage(bmp);

  using (var genericFormat = GetStringFormat())
  {
      var yearRect = new Rectangle(24, 13, 40, 15);
      var dayOfMonthRect = new Rectangle(10, 29, 70, 44);
      var dayNameRect = new Rectangle(10, 30, 70, 10);
      var monthNameRect = new Rectangle(10, 61, 70, 10);

      using(var headerFont = new Font(&quot;Tahoma&quot;, 7.5f, FontStyle.Regular))
      using(var footerFont = new Font(&quot;Tahoma&quot;, 7.5f, FontStyle.Regular))
      using (var dayFont = new Font(&quot;Tahoma&quot;, 14, FontStyle.Bold))
      {
          var day = CurrentCulture.Calendar.GetDayOfMonth(displayDate).ToString();
          var month = CurrentCulture.Calendar.GetMonth(displayDate);
          var year = CurrentCulture.Calendar.GetYear(displayDate).ToString();
        
          var weekDay = CurrentCulture.Calendar.GetDayOfWeek(displayDate);
          var dayName = CurrentCulture.DateTimeFormat.GetDayName(weekDay);
          var monthName = CurrentCulture.DateTimeFormat.GetAbbreviatedMonthName(month);
        
          g.DrawString(year, headerFont, Brushes.White, yearRect, genericFormat);
          g.DrawString(day, dayFont, Brushes.Black, dayOfMonthRect, genericFormat);
          g.DrawString(dayName, footerFont, Brushes.Black, dayNameRect, genericFormat);
          g.DrawString(monthName, footerFont, Brushes.Black, monthNameRect, genericFormat);
      }
  }

  return new ImageResult { Image = bmp, ImageFormat = ImageFormat.Png };
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;a href=&quot;http://lh6.ggpht.com/_Z5KTIfnfuNs/SfRPQPntsmI/AAAAAAAAAOE/gz3ScPNikS0/s1600-h/CalendarBadge%5B14%5D.png&quot;&gt;&lt;img style=&quot;border: 0px none ; display: inline; margin-left: 0px; margin-right: 0px;&quot; title=&quot;CalendarBadge&quot; alt=&quot;CalendarBadge&quot; src=&quot;http://lh4.ggpht.com/_Z5KTIfnfuNs/SfRPUGljIaI/AAAAAAAAAOI/ytgRZXKpubI/CalendarBadge_thumb%5B12%5D.png?imgmax=800&quot; width=&quot;436&quot; border=&quot;0&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;Note that CurrentCulture property returns the running user's CultureInfo which will help 'Translating' the date value correctly for different Cultures. What we achieved is a nice calendar badge with render date values and it is not even constrained to our Canvas size. Hope this helps.
    </content>
  </entry>
  <entry>
    <title type="html">Farsi Library for the Web</title>
    <link rel="alternate" type="text/html" href="http://www.hightech.ir/SeeSharp/farsi-library-for-web"/>
    <id>http://www.hightech.ir/SeeSharp/farsi-library-for-web</id>
    <updated>2009-10-19T07:53:39.797</updated>
    <published>2008-12-26T14:50:00</published>
    <author>
      <name>HEskandari</name>
    </author>
    <category term="FarsiLibrary" />
    <category term="Calendars" />
    <content type="html" xml:lang="en">
      &lt;p&gt;There's been a lot of request for web and windows controls supporting multiple cultures and calendars, like the already existing WinForm Controls of Farsi Library. The existing ASP.NET Calendar control does not render correctly when used in other cultures and this is the case when you're using FA-IR culture. Although this problem is partially because FA-IR has a wrong calendar set for its default calendar (GregorianCalendar instead of PersianCalendar this has its own story too), there's no workaround. What I did was to create a new control to correctly render the calendar information in Gregorian Calendar, Persian Calendar and Hijri Calendar.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.hightech.ir/Images/BlogPics/FarsiLibraryForTheWeb.jpg&quot;&gt;&lt;img title=&quot;FADatePicker-Web&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;264&quot; alt=&quot;FADatePicker-Web&quot; src=&quot;http://www.hightech.ir/Images/BlogPics/FarsiLibraryForTheWeb.jpg&quot; width=&quot;345&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The control currently works exactly as ASP.NET calendar, meaning it supports all the use cases of standard ASP.NET calendar control like styling, using on update panels, etc. This control with a complementary DatePicker control will be added to the Farsi Library project as I'm planning for the next major release. The pre-beta sources will soon be available in case you are interested.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title type="html">Persian Calendar Problem</title>
    <link rel="alternate" type="text/html" href="http://www.hightech.ir/SeeSharp/persian-calendar-problem"/>
    <id>http://www.hightech.ir/SeeSharp/persian-calendar-problem</id>
    <updated>2009-10-19T13:54:14.823</updated>
    <published>2008-10-13T10:00:00</published>
    <author>
      <name>HEskandari</name>
    </author>
    <category term="FarsiLibrary" />
    <category term="General" />
    <category term="Calendars" />
    <content type="html" xml:lang="en">
      &lt;p&gt;If you've read my &lt;a href=&quot;http://blog.hightech.ir/2008/06/persiancalendar-and-net-framework.html&quot;&gt;older&lt;/a&gt; posts, you already know about the problem of FA-IR culture and the default calendar. When creating applications that run in different cultures and languages, Date specific controls like DatePickers, Scheduling controls, etc usually use current Culture's calendar to calculate dates, and to represent a DateTime instance to string representation. Also, control developers use DateTime.MinValue as a default (not set) value. But what happens when a culture's calendar does not accept DateTime.MinValue as a valid date? One example, of course, is our &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.globalization.persiancalendar.aspx&quot;&gt;PersianCalendar&lt;/a&gt; in which the least possible date is 22/03/622 (in Gregorian calendar) that maps to 1/1/1 in Persian calendar. &lt;br /&gt;&lt;br /&gt;

&lt;div class=&quot;center&quot;&gt;
&lt;a href=&quot;http://www.hightech.ir/images/BlogPics/FarsiLibrary_DateComparison.jpg&quot;&gt;&lt;img alt=&quot;Date Comparison&quot; src=&quot;http://www.hightech.ir/images/BlogPics/FarsiLibrary_DateComparison.jpg&quot; height=&quot;293&quot; width=&quot;624&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;It gets worse when you storing data in the database! Suppose a user that uses Gregorian Calendar has logged-in and selected a date in the valid range for Gregorian Calendar, but invalid for Persian Calendar (the red arrows in the picture). What happens when the first user saves the data, and then the user logged in with Persian Calendar tries to load it? You'll have a nice exception on your hand! (This, of course is a hypothetical example. It *might* not be possible to save the date prior to 1753 in some RDBMS). You can't even call ToString() method on DateTime instance that falls in the invalid range! &lt;br /&gt;&lt;/p&gt;  

&lt;pre class=&quot;brush:c-sharp&quot;&gt;
[Fact]
public void UsingInvalidDateRangeThrows()
{
 using (new CultureSwitchContext(new PersianCultureInfo()))
 {
    DateTime dt = DateTime.MinValue;
    Assert.Throws&amp;lt;ArgumentOutOfRangeException&amp;gt;(() =&amp;gt; dt.ToString());
 }
}

[Fact]
public void CanConvertToStringWithInvariantCulture()
{
 using (new CultureSwitchContext(new PersianCultureInfo()))
 {
     DateTime dt = DateTime.MinValue;
     Assert.DoesNotThrow(() =&amp;gt; dt.ToString(CultureInfo.InvariantCulture));
 }
}
&lt;/pre&gt;

&lt;p&gt;You'll get an exception complaining :&lt;/p&gt;&lt;p&gt;&lt;em&gt;Specified time is not supported in this calendar. It should be between 03/21/0622 00:00:00 (Gregorian date) and 12/31/9999 23:59:59 (Gregorian date), inclusive.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;I think I understand why guys at Microsoft BCL decided not to set PersianCalendar as the default calendar of FA-IR culture : Because your application / component may break if you switch to FA-IR culture, but why not set it as an OptionalCalendar?&lt;/p&gt;&lt;p&gt;Lesson learned : Avoid calling DateTime.ToString recklessly, specially if you're developing a Custom Control or creating a multi-cultured application. Pay attension to Calendar.MinSupportedDateTime property.&lt;/p&gt;
    </content>
  </entry>
</feed>
