locked
Desing of Hijri/Gregorian Converter Business Object / Class using .NET. RRS feed

  • Question

  • User1677734741 posted

    I am developing a Business Object using .NET to perform Conversion from/to Hijri/Gregorian Calendar. Although there is a class in .NET for this purpose, but, still there is a good chance there will be a mistake by at least one day +/- in few cases. In any case, I may depend on this class for conversion, when needed. On the other hand, I already developed this conversion logic under MS Access, and I want to re-use parts of the work done of it in .NET. 

    I will post the BO specs summary here to give you an idea about the requirement, so that I can get your feedback, and I will be posting questions mainly related to how to make this BO most efficient, because eventually it will be exposed via a web service.

    The Database:

    I am storing the required data in tables in MS Access DB, and following is a sample of such tables:

    tDOW
    DOW DOWArb DOWEng
    1 سبت Sat
    2 أحد Sun
    3 إثنين Mon
    4 ثلاثاء Tue
    5 أربعاء Wed
    6 خميس Thu
    7 جمعة Fri

    tHMonth
    HMnth HMnthNameArb HMnthNameEng DftDays
    1 محرم Muharram 29
    2 صفر Safar 30
    3 ربيع الأول Rabii' I 29
    4 ربيع الآخر Rabii' II 29
    5 جمادى الأولى Jumada' I 30
    6 جمادى الآخرة Jumada' II 29
    7 رجب Rajab 29
    8 شعبان Sha'ban 30
    9 رمضان Ramadan 30
    10 شوال Shawal 29
    11 ذو القعدة Dhul-Qa'dah 30
    12 ذو الحجة Dhu Al-Hijja 30

    Following is the main conversion table which is updated/initialized at the beginning of each new Hijri Year and when needed (mainly at the beginning of Ramadan):

    tHYearMonth

    HYear HMnth DaysCnt FromDateGrg ToDateGrg
    1429 1 29 10/01/2008 07/02/2008
    1429 2 30 08/02/2008 08/03/2008
    1429 3 29 09/03/2008 06/04/2008
    1429 4 29 07/04/2008 05/05/2008
    1429 5 30 06/05/2008 04/06/2008
    1429 6 29 05/06/2008 03/07/2008
    1429 7 29 04/07/2008 01/08/2008
    1429 8 30 02/08/2008 31/08/2008
    1429 9 30 01/09/2008 30/09/2008
    1429 10 29 01/10/2008 29/10/2008
    1429 11 30 30/10/2008 28/11/2008
    1429 12 30 29/11/2008 28/12/2008

    BO Class Specs:

    Class Name: HijriGreg
    Class Member:

    1. LastTimeDataLoaded: The date/time the data was loaded from
    2. DayOfWeek: DataSet/DataView loaded from the related table above.
    3. HijriMonth: DataSet/DataView loaded from the related table above.
    4. HijriYearMonth: DataSet/DataView loaded from the related conversion table above.

    Do you have any comment on how to represent the above data in .NET ? I was thinking to use XML, bu I need a quick and easy way to perform look-up which is probably better done using DataView? I need help in this area.

    Comments about Class Members:

    I want to load the above DataSet/Views once and make them available to all users (Application Scope) to make it more efficient by minimizing Database Access Operations.

    Only for the DataSet of HijriYearMonth Conversion Table must be re-loaded say once every few days or something like that, because it may change at the beginning of every month at worst case.

    I can make the above members as Public Shared, but this will violate the concept of Encapsulation, so how I can define them in such a way to make them persistent and available to all the users of the application ? Of course, in this case I have to Synchronize the Locks to the shared resources to make it thread safe. I need help in this area.

    Initialization Methods:

    I think the initialization methods should be called when needed and must be private. For example:

    - Sub HijriGreg.InitializeIfNeeded(): It will check if the class variables are Nothing, and load each each one at a time. For the case of the HijriYearMonth Conversion Table, it will check if the data is expired (using LastTimeDataLoaded) and re-loaded if needed.

    - Method/Function HijriGreg.GetHijriFromGreg(...) as String:
      - Input: GregDateDMY, a String Variable of input Gregorian Date in DD/MM/YYYY format.
      - Output: Returns a String of HijtiDateDMY in DD/MM/YYY format.
      I am not sure if this method will be Shared or not ? I need help in this area..

    - Method/Function HijriGreg.GetGregFromHijri(...) as String:
      - Input: HijriDateDMY, a String Variable of Hijri Date in DD/MM/YYYY format.
      - Output: Returns a String of HijtiDateDMY in DD/MM/YYY format.
      I am not sure if this method will be Shared or not ? I need help in this area..

    The algorithms for the above methods are available with me and already implemented in VBA and it is working properly for the past 5 years.

    How to make the BO HijriGreg visible to all users:

    Should I create an instance of the HijriGreg Object and store it in Application(..) variable ? So that in the subsequent calls to this object, it can be restored from the Application Variable Objects.

    How to make such process thread safe ?

    I need help in this area.

    After implementing this BO, I need to wrap it in a Web Service. I will talk about this later.

    Thank you for your help in advance.

    Tarek.

    Wednesday, May 7, 2008 9:49 AM

All replies

  • User1677734741 posted

    I did some research and almost made up my mind on how to implement this project.

    I will using Singleton pattern implementation for the HijriGreg class as follows:

    public class HijriGreg

    private shared _Singleton as HijriGreg = new HijriGreg()

    private sub new ()

    ' Load the Dataset and Dataviews here.

    ' Only the DataViews will have to be maintained, and the DataSet could be destroyed after initialization is completed. 

    end sub 

    public shared readonly property Singleton()

    get

      retrun _Signleton

    end get

    end property

    public function HijriToGreg(HijriDateDMY as string) as string

    .... logic goes here

    ... must synchronize this function.

    ...

    end function

     

    public function GregToHijri(GregDateDMY as string) as string

    .... logic goes here

    ... must synchronize this function.

    ...

    end function

    end class 

    I have developed a sample Class Library to test to this Singleton concept and it worked 100% as expected.

    As a mater of fact, most questions I had have been answered after I developed the sample project.

    Since there is only one object, then any variables updated inside this object must be synchronized, so all methods (public shared or public only) will have to be synchronized. The only exception to this is the Static Initialization of the Singleton during declaration, as in this case .NET framework will ensure that the update is synchronized.

    This means that the methods "HijriToGreg()" and "GregToHijri()" must be synchronized. Please correct me if I am wrong.

    I noticed that the Singleton object is created at the first time a reference is made to the class members. But, I could not find and easy way to destroy the object, and force re-initialization, and this only could happen after I restart IIS. I also implemented IDisposable Class but still not working. But if I use "lazy initialization" i.e. manual creation of the Singleton, then I can control the Disposal and re-creation of the object.

    Tarek.
    Saturday, May 10, 2008 6:44 PM
  • User1046815810 posted

    Check out these classes

    System.Globalization.HijriCalendar

    System.Globalization.GregorianCalendar

    you can pass DateTime between the two and have most of the work done for you by .Net

    check out this sample using A Gregorian and Hebrew Calendar

    http://www.ziporah-greve.net/prog/jewish-csharp.html

    Sunday, May 11, 2008 5:05 AM
  • User1677734741 posted

    Thanks a lot.

    As a mater of fact, I already know about these classes, and already used them. The problem is that there will always be a possibility of an error of +/- 1 day at least.

    You need to implement an ADJUSTMENT Logic. And the easiest way is to use a table. The method I presented above is one of the methods to implement adjustment.

    I can simple check the range of the input date to be converted. If it is outside the coverage of the conversion table, then I will use these .NET Classes.

    I was wondering if there is any comment on the approach I presented above from the design/implementation perspectives.

    Tarek.

    Sunday, May 11, 2008 6:59 AM
  • User1677734741 posted

    Completed the design and implementation of HijriGregCalendar class.

    Mainly, it has the following 2 public methods:

    1. Public Function HijriToGreg(HijriDateDMY as String) as string,

    2. Public Function GregToHijri(GregDateDMY as String) as String.

    and one Public Shared Method:

    public shared GetSginleton() as HijriGregCalendar

    And I used CSLA .NET Data Access approach to load the lookup tables into the DataViews members of this class.

    Everything is working properly when I test the above class from a normal ASPX Web Page.

    Note: Also used .NET Gregorian Calendar and Um-Alqora (excuse my spelling) Hijri Calendar to do the conversion when the input dates are outside the coverage of the in-house developed mapping table.

    The Problem: 

    But, when I tried to develop a Web Service wrapper for the above class, I am unable to call the GetSingleton() method to get shared instance object of this class. This method is not visible from Web Service. Other methods are visible.

    Any idea why ? What is the proper way to provide the above functionality under a Web Service ?

    Tarek.
    Saturday, May 17, 2008 3:50 PM
  • User1677734741 posted

    Everything is OK now. In case someone is interested, I am able to call the HijriGregCalendar via a Web Service Wrapper Class from VB Script as follows:

     
    Const BaseWebServiceURL = "http://server/cslawebservices/HijriGreg/"
    Const WebService = "HijriGregService.asmx"
    Const Operation = "HijriToGreg"
    Const prmHijriDateDMY= "1/5/1429"
    Const prmGregDateDMY = "1/5/2008"
    dim PostedURL
    dim xmlhttp
    ' Create the HTTP object
    Set xmlhttp = CreateObject("Microsoft.XMLHTTP")
    PostedURL = BaseWebServiceURL & WebService
    'msgbox "Posted URL = " & PostedURL
    'xmlhttp.open "POST", PostedURL, false
    'xmlhttp.setRequestHeader "Content-Type", "text/xml"

    'MsgBox xmlhttp.responseText
    MsgBox "Hijri conversion from " & prmHijriDateDMY & " to Greg is: " & HijriToGreg(prmHijriDateDMY)

    MsgBox "Gregorian conversion from " & prmGregDateDMY & " to Hijri is: " & GregToHijri(prmGregDateDMY)

    function HijriToGreg(prmHijriDateDMY)
    xmlhttp.open "POST", PostedURL, false
    xmlhttp.setRequestHeader "Content-Type", "text/xml" xmlhttp.setRequestHeader "SOAPAction", "WebServices.HijriGreg/HijriToGreg" PostMsg = _ "<?xml version=""1.0"" encoding=""utf-8""?> " & _
    "<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""> " & _
    "<soap:Body> " & _
    " <GregToHijri xmlns=""WebServices.HijriGreg""> " & _
    " <GregDateDMY>" & prmGregDateDMY & "</GregDateDMY> " & _
    " </GregToHijri> " & _
    "</soap:Body> " & _
    "</soap:Envelope>" xmlhttp.send PostMsg 'MsgBox xmlhttp.responseText HijriToGreg = xmlhttp.responseXML.selectSingleNode("//HijriToGregResult").text
    end function

    function GregToHijri(prmGregDateDMY)
    'Set xmlhttp = CreateObject("Microsoft.XMLHTTP")
    'PostedURL = BaseWebServiceURL & WebService
    'msgbox "Posted URL = " & PostedURL
    xmlhttp.open "POST", PostedURL, false
    xmlhttp.setRequestHeader "Content-Type", "text/xml" xmlhttp.setRequestHeader "SOAPAction", "WebServices.HijriGreg/GregToHijri" PostMsg = _ "<?xml version=""1.0"" encoding=""utf-8""?> " & _
    "<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""> " & _
    "<soap:Body> " & _
    " <GregToHijri xmlns=""WebServices.HijriGreg""> " & _
    " <GregDateDMY>" & prmGregDateDMY & "</GregDateDMY> " & _
    " </GregToHijri> " & _
    "</soap:Body> " & _
    "</soap:Envelope>" xmlhttp.send PostMsg 'MsgBox xmlhttp.responseText GregToHijri = xmlhttp.responseXML.selectSingleNode("//GregToHijriResult").text
    end function
     

    The above script can easily be used in Lotus Notes and in VBA under MS Office Products, and also in Client-Side Script in HTML, with minor conversion as per need. 

    Tarek.

    Monday, May 19, 2008 5:57 PM
  • User442844886 posted

    i have the same pb

    +1/-1  problem i believe taht the solution is to cal web service but i dont know how to make it


    this one convert right  can i make like this one

    http://www.islamicfinder.org/dateConversion.php?mode=ger-hij&day=28&month=6&year=2010&date_result=1


    Monday, June 28, 2010 6:49 AM
  • User1677734741 posted

    From our side, I am not using a Public Web Service. I have developed a custom DLL and a Web Service Wrapper that will do the needed conversion. This DLL function will work as per Um-Al-Qura Callendar, which is based on a table which has 12 records for every year.

    Tarek.

    Monday, June 28, 2010 7:06 AM
  • User442844886 posted

    so the table in DB??? and update it everymonth !!! using this service right?

    Wednesday, June 30, 2010 2:27 PM
  • User1677734741 posted

    The table is updated by the DB Admin, based on the table available from the source. The web service was not desinged to implement the update.

    The web service will do the conversion using the table as a priority, and if the provided date is outside the range of the table, it falls back to the .NET Hijri Calendar Support.

    Mind you that the web service accepts String and Returns String. So, this is not a Calendar User Control.

    I hope this helps.

    Tarek.

    Wednesday, June 30, 2010 3:21 PM
  • User2106330258 posted

    Hi Tarek, could you give me the source code to that local web service you developed to convert from Gregorian to Hijri? Do you perhaps know of any public web service, in addition to this one, which may help prevent the +-1 out of synch hijri date problem? I am developing an application for people in Bahrain and they are strict with dates and their accuracy for this current system.


    Thanks, any help is appreciated.

    Monday, November 15, 2010 8:03 AM
  • User1677734741 posted

    Sure I will post the complete source code. Could you please wait after Hajj? I will be back on frida.

    I don't know of such web service.

    Tarek.

    Monday, November 15, 2010 6:43 PM
  • User762298549 posted

    سلام

    بعد إطلاعي عالموضوع .. أشكرك جزيل الشكر وتقديرا للمجهود

    أريد أن أقول أن مكتبة
    System.Globalization
    مدعومة بـ 
    HijriCalendar
    و
    DateTimeFormatInfo
    قد تساعدانك أكثر

    Friday, November 19, 2010 1:24 PM
  • User1677734741 posted

    jbedford,

    Sorry for the late reply.

    Please find below the files needed for the Hijri Gregorian Converter.

    http://bit.ly/dj2qCj 

    Mind you I developed it about 2 years ago when I was learning CSLA.NET.

    You need to put the connection string in web.config for the Database "HijriGreg.mdb". Only take what you need from web.config.

    The main library code is placed in "HijriGregCalendar.vb". To test the code from Web Page, I have developed "HijriGregUtil.aspx" and "HijriGregUtil.aspx.vb". Simple webservice wrapper is in "HijriGregService.asmx". I have developed several other front-end programs in Lotus Notes LotusScript and JavaScript to test this Web Service and all are working fine.

    Connection String referece can be changed from "Database.DBHijriGreg" to ConnectionStrings("DBHijriGreg").ConnectionString, or create a Database Module with this property:

    Public Module Database
      Public ReadOnly Property DBHijriGreg() As String
            Get
                Return ConnectionStrings("DBHijriGreg").ConnectionString
            End Get
      End Property
    End Module


    I hope this will be of help.

    Tarek.

    Sunday, November 21, 2010 4:25 AM
  • User1677734741 posted

    Hi All,

    I also put together JavaScript code to do the same. I collected it from one website, and placed the code inside Adobe LiveCycle PDF Document. Looks like it is working fine.

    If any one is interested, please let me know.

    Tarek

    Tuesday, March 12, 2013 10:06 AM