Thursday, February 23, 2017

Age Calculator - Calculating difference between dates

Dear friends in most of the cases you need to work on dates. I had been stuck while calculating exact age of a person or total experience in Years, Months and Days. So, I googled to find the code that can help me to work on. But, I found that most of the programmers made mistakes in calculating exact difference in days or the code found to be too much complex to understand.

Actually calculating the date difference is so easy. Its similar to find the difference between two numbers, yet its quite tricky to calculate no of days exactly. I haven't added any validation check to avoid getting negative no of years if 'from date' is greater than 'to date'.

I created class library with name "AgeCalculator" and another console application "AgeCalculator.Tests" to test the classes in class library.

You can get the complete project here.

AgeCalculator consist of two class files Age.cs and Calculator.cs. Code snippets of these files are listed as follows.


File Name : Age.cs

namespace AgeCalculator
{
    /// <summary>
    ///
    /// </summary>
    public class Age
    {
        public int Days { get; set; }
        public int Months { get; set; }
        public int Years { get; set; }

        /// <summary>
        /// Returns a <see cref="System.String" /> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String" /> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return string.Format("{0} Year(s) {1} Month(s) {2} Day(s)", this.Years, this.Months, this.Days);
        }
    }
}


File Name : Calculator.cs

using System;
namespace AgeCalculator
{
    /// <summary>
    /// Calculates the age from specified dates.
    /// </summary>
    public class Calculator
    {
        /// <summary>
        /// Calculates the age from specified from date and to date.
        /// </summary>
        /// <param name="fromDate">From date.</param>
        /// <param name="toDate">To date.</param>
        /// <param name="includeEndDay">if set to <c>true</c> [include end day].</param>
        /// <returns></returns>
        public static Age Calculate(DateTime fromDate, DateTime toDate, bool includeEndDay)
        {
            var days = toDate.Day - fromDate.Day + (includeEndDay ? 1 : 0);
            var months = toDate.Month - fromDate.Month;
            var years = toDate.Year - fromDate.Year;

            // If days are -ve then borrow no of days from last month.
            if (days < 0)
            {
                // If its January then borrow no of days from last year December.
                if (toDate.Month == 1)
                {
                    days = days + DateTime.DaysInMonth(toDate.Year - 1, 12);
                }
                else // If its not January then borrow days from last month of current year.
                {
                    days = days + DateTime.DaysInMonth(toDate.Year, toDate.Month);
                }

                months = months - 1;
            }

            // If months are -ve then borrow 12 months from years.
            if (months < 0)
            {
                months = months + 12;
                years = years - 1;
            }

            return new Age { Days = days, Months = months, Years = years };
        }

        /// <summary>
        /// Calculates the age from specified date.
        /// </summary>
        /// <param name="fromDate">From date.</param>
        /// <param name="includeEndDay">if set to <c>true</c> [include end day].</param>
        /// <returns></returns>
        public static Age Calculate(DateTime fromDate, bool includeEndDay)
        {
            return Calculator.Calculate(fromDate, DateTime.Today, includeEndDay);
        }
    }
}

The code snippet of Calculate function is self explanatory. Firstly it is calculating the difference directly between years, months and days. After that if days are negative then it will borrow no of days from last month of toDate. If no of months is negative then it will borrow 12 months from last year of toDate.

Following are code snippets to calculate the date difference.


File Name : Program.cs

using System;

namespace AgeCalculator.Tests
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            DateTime birthDate = new DateTime(1986, 8, 12);
            Console.WriteLine("Age of a Person till {0:dd-MMM-yyyy} : {1}.", DateTime.Today, Calculator.Calculate(birthDate, false));

            // Experience between dates 06-Jan-2011 to 01-Feb-2016.
            Console.WriteLine("Total Experience : {0}.", Calculator.Calculate(new DateTime(2011, 1, 6), new DateTime(2017, 2, 1), false));
        }
    }

}

Here, system date is : 23-Feb-2017, so after executing above code you will get following result.












I hope this will help. You can use the code as is or change the code logic as per your requirement. Please suggest improvements if any. Enjoy the coding...

Tuesday, April 9, 2013

How to get day of a date without using date functions

In most of cases we use some date functions directly to get day of that date. But there is a logical patter that calender follows and hence it is possible to find out the day of any valid date that we know and following code sample works well in that situations. Purpose of this code is show that the days mentioned in the calender follows some common logical rules and hence it is easy to find the day of that date.

Create a new console application say "DayCalculatorDemo" then copy and paste the following code sample as follows....

FileName : Program.cs

using System;

namespace DayCalculatorDemo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("The day of 12 August 1986 is " + DayCalculator.GetDayFromDate(1986, 8, 12));
            Console.ReadKey();
        }
    }

    public class DayCalculator
    {
        public static String GetDayFromDate(int year, int month, int day)
        {
            String strDay = String.Empty;

            if(!IsDateValid(year, month, day))
            {
                return String.Empty;
            }

            int yearOffset = year % 28;
            int yearFactor = (yearOffset % 7) + (int)(yearOffset / 4) - (yearOffset % 4 == 0 ? 1 : 0);

            int monthFactor = 0;
            switch(month)
            {
                case 1:
                case 10:
                    monthFactor = 0;
                break;

                case 5:
                    monthFactor = 1;
                break;

                case 8:
                    monthFactor = 2;
                break;

                case 2:
                case 3:
                case 11:
                    monthFactor = 3;
                break;

                case 6:
                    monthFactor = 4;
                break;

                case 9:
                case 12:
                    monthFactor = 5;
                break;

                case 4:
                case 7:
                    monthFactor = 6;
                break;
            }

            if(IsLeapYear(year) && month > 2)
            {
                monthFactor++;
            }

            int dayFactor = day % 7;

            int dayIndex = (yearFactor + monthFactor + dayFactor + 6) % 7;

            switch(dayIndex)
            {
                case 1:
                    strDay = "Sunday";
                break;

                case 2:
                    strDay = "Monday";
                break;

                case 3:
                    strDay = "Tuesday";
                break;

                case 4:
                    strDay = "Wednesday";
                break;

                case 5:
                    strDay = "Thursday";
                break;

                case 6:
                    strDay = "Friday";
                break;

                case 0:
                    strDay = "Saturday";
                break;
            }

            return strDay;
        }

        private static bool IsDateValid(int year, int month, int day)
        {
            bool isValid = true;

            if(day > 31)
            {
                isValid = false;
            }
            else if(month > 12)
            {
                isValid = false;
            }
            else if(year <= 0 || month <= 0 || day <= 0)
            {
                isValid = false;
            }
            else if(month == 2 && (!IsLeapYear(year)) && day >= 29)
            {
                isValid = false;
            }
            else if(month == 2 && day >= 30)
            {
                isValid = false;
            }
            else if((month == 2 || month == 4 || month == 6 || month == 9 || month == 11) && (day > 30))
            {
                isValid = false;
            }

            return isValid;
        }

        private static bool IsLeapYear(int year)
        {
            return (year % 4 == 0 && year % 100 != 0) || (year % 100 == 0 && year % 400 == 0);
        }
    }
}


above code is free to use and modify. You can suggest any changes in the above code. It can work for at least 400 years perfectly.

Saturday, April 6, 2013

Convert Number Into Word

In most of cases we need to show the number (currency) in words as per Indian Standard form. So, I have created a small program that may be found to be helpful to us. I have created new console application that shows how the number can be shown in words based on Indian Standard form. Following screen shot itself shows how program result will it be.

Here is complete code...

File Name : Program.cs

using System;

namespace NumberToWordDemo {
    public class Program {
        public static void Main(String[] args)  {
            System.Console.WriteLine("Actual Number : " + int.MaxValue + "\nNumber In Word : " + NumberDescriptor.NumberToWord(int.MaxValue));
            System.Console.ReadKey();
        }
    }

    public class NumberDescriptor
    {
        public static String UnitToWord(int x)
        {
            String strNumber = "Zero";
            switch(x)
            {
                case 0:
                    strNumber = "Zero";
                break;
                case 1:
                    strNumber = "One";
                break;
                case 2:
                    strNumber = "Two";
                break;
                case 3:
                    strNumber = "Three";
                break;
                case 4:
                    strNumber = "Four";
                break;
                case 5:
                    strNumber = "Five";
                break;
                case 6:
                    strNumber = "Six";
                break;
                case 7:
                    strNumber = "Seven";
                break;
                case 8:
                    strNumber = "Eight";
                break;
                case 9:
                    strNumber = "Nine";
                break;
            }
            return strNumber;
        }

        public static String TensToWord(int x)
        {
            int tensValue = x/10;
            int unitValue = x%10;
            String strNumber = "";

            if(x > 0 && x < 10)
            {
                strNumber = UnitToWord(unitValue);
            }
            else if(x >= 10 && x <= 19)
            {
                switch(x)
                {
                    case 10:
                        strNumber = "Ten";
                    break;
                    case 11:
                        strNumber = "Eleven";
                    break;
                    case 12:
                        strNumber = "Twelve";
                    break;
                    case 13:
                        strNumber = "Thirteen";
                    break;
                    case 14:
                        strNumber = "Fourteen";
                    break;
                    case 15:
                        strNumber = "Fifteen";
                    break;
                    case 16:
                        strNumber = "Sixteen";
                    break;
                    case 17:
                        strNumber = "Seventeen";
                    break;
                    case 18:
                        strNumber = "Eighteen";
                    break;
                    case 19:
                        strNumber = "Nineteen";
                    break;
                }
            }
            else if(x >= 20 && x <= 99)
            {
                switch(tensValue)
                {
                    case 2:
                        strNumber = "Twenty";
                    break;
                    case 3:
                        strNumber = "Thirty";
                    break;
                    case 4:
                        strNumber = "Fourty";
                    break;
                    case 5:
                        strNumber = "Fifty";
                    break;
                    case 6:
                        strNumber = "Sixty";
                    break;
                    case 7:
                        strNumber = "Seventy";
                    break;
                    case 8:
                        strNumber = "Eighty";
                    break;
                    case 9:
                        strNumber = "Ninety";
                    break;
                }

                if(unitValue > 0)
                {
                    strNumber = strNumber + " " + UnitToWord(unitValue);
                }
            }

            return strNumber;
        }

        public static String NumberToWord(int x)
        {
            int offset = 1000000000;
            int index = 0;
            String strNumber = "";

            while(offset >= 1000)
            {
                if(x / offset > 0)
                {
                    strNumber += TensToWord(x / offset) + " " + Position(index) + " ";
                }

                index++;
                x = x % offset;
                offset = offset / 100;
            }

            if(x / 100 > 0)
            {
                strNumber += TensToWord(x / 100) + " " + Position(index) + " ";
                x = x % 100;
            }

            if(x > 0)
            {
                strNumber += TensToWord(x);
            }

            return strNumber.Trim();
        }

        private static String Position(int index)
        {
            String strIndex = "";

            switch(index)
            {
                case 0:
                    strIndex = "Billion";
                break;
                case 1:
                    strIndex = "Crore";
                break;
                case 2:
                    strIndex = "Lac";
                break;
                case 3:
                    strIndex = "Thousand";
                break;
                case 4:
                    strIndex = "Hundred";
                break;
            }

            return strIndex;
        }
    }
}



Above code can be modified or can be used as it is for free.

Tuesday, February 12, 2013

Stop Watch Using Background Worker

I am showing you how to use background worker to make an interesting stop watch.
Now create new window based application named as "StopWatchDemo", change the form name with "frmMain" and design it as shown in image below...


 Now give name to the buttons sequentially as btnStart, btnStop, btnClose respectively.Give name "lblStopWatch" to label containing StopWatch. Give click events to each button. And here is complete code...

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace StopWatchDemo
{
    public partial class frmMain : Form
    {
        Stopwatch stopWatch = null;
        BackgroundWorker backgroundWorker = null;
       
        public frmMain()
        {
            InitializeComponent();

            stopWatch = new Stopwatch();
            backgroundWorker = new BackgroundWorker();

            backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
            backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;

            btnStop.Enabled = false;
        }

        void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            TimeSpan timeSpan = stopWatch.Elapsed;
            lblStopWatch.Text = String.Format("Time : {0:00}:{1:00} sec", timeSpan.Minutes, timeSpan.Seconds);
        }

        void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            while(true)
            {
                backgroundWorker.ReportProgress(0);
                System.Threading.Thread.Sleep(1000);
                if (!stopWatch.IsRunning)
                {
                    break;
                }
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            backgroundWorker.RunWorkerAsync();
            stopWatch.Start();

            btnStart.Enabled = false;
            btnStop.Enabled = true;
            btnClose.Enabled = false;
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            backgroundWorker.CancelAsync();
            stopWatch.Stop();
            stopWatch.Reset();

            btnStart.Enabled = true;
            btnStop.Enabled = false;
            btnClose.Enabled = true;
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

Now Start debugging, window will look like this as follows...



Now play with this....
This example shows how to use background worker facility given by .NET, it can be used in serious applications as I have used in some live projects...

Monday, February 11, 2013

Single Instace of an Application

Hi guys most of cases we don't want to make multiple instants of applications to be executed in single machine, I am providing a code span to prevent this problem as follows...

In most of the window based applications code looks like this...


[STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmMainForm());
        }


Now I am made some changes in above code it looks like this....


[STAThread]
        static void Main()
        {
            //Make Single Instace of an Application I am using Mutex
            bool createdNew;
            using (new System.Threading.Mutex(false, "SingleWindow", out createdNew))
            {
                if (createdNew)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new frmMainForm());
                }
            }
        }

Here "SingleWindow" is the name of exe or project name that I am making and System.Threading.Mutex function updates value of boolean veriable createdNew true if no exe is running in the machine named "SingleWindow". So, code is self explanatory that what I have done...

Sunday, February 10, 2013

XOR Cipher


Hi guys I would like to publish a simple way to create your own cipher using c#, here is complete code for it....


class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //XORCipher objXORCipher = new XORCipher("dinesh", "0123456789ABCDEF");
                XORCipher objXORCipher = new XORCipher();
                String textToEncrypt = "This is Test String...";
                String encText = objXORCipher.Encrypt(textToEncrypt);
                String finalText = objXORCipher.Decrypt(encText);
                Console.Write("\n\nOriginal  Text : " + textToEncrypt);
                Console.Write("\n\nEncrypted Text : " + encText);
                Console.Write("\n\nDecrypted Text : " + finalText);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.Write("\n\nDone...");
            Console.ReadKey();
        }
    }

    public class XORCipher
    {
        char[] key = new char[0];
        String cipherString = String.Empty;

        public XORCipher()
        {
            key = "DINESH".ToCharArray();
            cipherString = "0123456789ABCDEF";
        }

        public XORCipher(String key, String cipherString)
        {
            this.key = key.ToCharArray();
         
            if (cipherString.Length != 16)
            {
                throw new Exception("Invalid cipher string");
            }

            this.cipherString = cipherString;
        }

        public String Encrypt(String textToEncrypt)
        {
            String val = String.Empty;
            char[] myString = textToEncrypt.ToCharArray();

            byte[] demoString = new byte[myString.Length];

            for (int i = 0; i < demoString.Length; i++)
            {
                demoString[i] = (byte)(myString[i] ^ key[i % key.Length]);
            }

            foreach (byte ok in demoString)
            {
                String demo = DecimalToBinary((byte)ok);
                for (int i = 0; i < (demo.Length / 4); i++)
                {
                    //Console.Write(" " + demo.Substring(i * 4, 4));
                    val += cipherString.Substring(Convert.ToInt16(demo.Substring(i * 4, 4), 2), 1);
                }
            }

            return val;
        }

        public String Decrypt(String textToDecrypt)
        {
            if (textToDecrypt.Length % 2 != 0)
            {
                throw new Exception("Invalid text to decrypt");
            }

            String val = textToDecrypt;
            String decString = String.Empty;
            for (int i = 0; i < val.Length; i = i + 2)
            {
                String highNibble = DecimalToBinary((byte)(cipherString.IndexOf(val.Substring(i, 1)))).Substring(4);
                String lowNibble = DecimalToBinary((byte)(cipherString.IndexOf(val.Substring(i + 1, 1)))).Substring(4);
                char ok = (char)(Convert.ToInt16(highNibble + lowNibble, 2));
                decString += (char)(ok ^ key[(i / 2) % key.Length]);
            }

            return decString;
        }

        public String DecimalToBinary(byte decNumber)
        {
            int maxSize = (sizeof(byte)) * 8;
            String val = String.Empty;
            byte myVal = (byte)decNumber;

            for (int i = 0; i < maxSize; i++)
            {
                val = "" + (myVal % 2 == 0 ? 0 : 1) + val;
                myVal = (byte)(myVal / 2);
            }
         
            return val;
        }
    }

Age Calculator - Calculating difference between dates

Dear friends in most of the cases you need to work on dates. I had been stuck while calculating exact age of a person or total experience i...