LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-20-2007, 06:09 PM   #1
BlueNotes
LQ Newbie
 
Registered: Oct 2007
Posts: 6

Rep: Reputation: 0
Need help to output the Chinese animal sign according to the year of birth


Hello.

I have wrote a bash shell script that will output your age in years and months, the day of the week you were born and the amount of days you have seen in the 21 century. I want the script to also output the Chinese animal sign according to your year of birth. The symbols repeat every 12 years. Example:

The year 1960 (Jan.1 to Dec. 31) = Rat, 1961 = Ox, 1962 = Tiger, 1963 = Rabbit, 1964 = Dragon, 1965 = Snake, 1966 = Horse, 1967 = Goat, 1968 = Monkey, 1969 = Rooster, 1970 = Dog, 1971 = Pig

I was thinking about using a case statement along with something like this Sign=$(($Year % 12)). It's not really working out for me so can you guys help me out?
Thanks.
 
Old 10-20-2007, 07:07 PM   #2
MensaWater
LQ Guru
 
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, CoreOS, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 7,831
Blog Entries: 15

Rep: Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669
Something like this would work:

year=$1
remainder=`expr $year % 12`
case $remainder in
0) sign=Monkey ;;
1) sign=Rooster ;;
2) sign=Dog ;;
3) sign=Pig ;;
4) sign=Rat ;;
5) sign=Ox ;;
6) sign=Tiger ;;
7) sign=Rabbit ;;
8) sign=Dragon ;;
9) sign=Snake ;;
10) sign=Horse ;;
11) sign=Goat
esac
echo $sign

The $1 would be input from command line - to incorporate this in your script you can determine where to get the $year variable from - I just did the above so I'd have a self contained script.

The "% 12" is the modulo function that returns the remainder of the division. Since you're on a 12 year cycle you'll have repeating remanders 0 through 11 (12 different values) and Monkey is the one that has 0 (whereas Rat has a remainder of 4). So the script starts at Monkey even if that isn't where the Chinese calendar starts. It still gives you the right values.
 
Old 10-20-2007, 08:06 PM   #3
BlueNotes
LQ Newbie
 
Registered: Oct 2007
Posts: 6

Original Poster
Rep: Reputation: 0
Thanks

Thanks, that worked perfectly. I was close, but didn't have the signs in the correct order.
 
Old 10-21-2007, 03:22 AM   #4
BlueNotes
LQ Newbie
 
Registered: Oct 2007
Posts: 6

Original Poster
Rep: Reputation: 0
Now I have a new problem. If I enter the date 18900831 I get an error. I think it's because of the method I used to get the day of the week the user was born. here's what I did; Dow=$(date -d "$BirthDate" | cut 1-4). BirthDate being what the user entered. It's in the format YYYYMMDD.

I have realized that the date command would not display a date of 1901 or earlier. Is there another way that I can get around this? Or another method I could use to output the day of the week the user was born?
Thanks in advance.
 
Old 10-21-2007, 03:51 AM   #5
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
If you are to do a lot of date manipulation shell script is not a good choice - it is really not suitable for the task... You will end up spawning lots of processes to date and other programs to get your job done. It would be better to use a language which can manipulate dates more easily.

Perl is a good choice IMO since it is installed on most systems, and it has a few easy-to-use modules suited to the task, specifically Date::Parse and Date::Format. An example of it's use:
Code:
% cat test_program.pl
#!/usr/bin/perl

use strict;
use warnings;

use Date::Format;
use Date::Parse;

print time2str("Day of week is: %a. (%C)\n", str2time("20071021"));

% ./test_program.pl
Day of week is: Sun. (Sun Oct 21 00:00:00 BST 2007)
 
Old 10-21-2007, 04:21 AM   #6
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by matthewg42 View Post
If you are to do a lot of date manipulation shell script is not a good choice - it is really not suitable for the task... You will end up spawning lots of processes to date and other programs to get your job done. It would be better to use a language which can manipulate dates more easily.

Perl is a good choice IMO since it is installed on most systems, and it has a few easy-to-use modules suited to the task, specifically Date::Parse and Date::Format. An example of it's use:
Code:
% cat test_program.pl
#!/usr/bin/perl

use strict;
use warnings;

use Date::Format;
use Date::Parse;

print time2str("Day of week is: %a. (%C)\n", str2time("20071021"));

% ./test_program.pl
Day of week is: Sun. (Sun Oct 21 00:00:00 BST 2007)
just curious, can these modules format dates before 1901? as what OP has requested?
 
Old 10-21-2007, 04:36 AM   #7
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Quote:
Originally Posted by ghostdog74 View Post
just curious, can these modules format dates before 1901? as what OP has requested?
I think so...

[checks]

Erk. Nothing before 1970!
 
Old 10-21-2007, 05:02 AM   #8
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
So after ghostdog74's question, and the subsequent discovery that the Date::Parse / Date::Format modules don't seem to like dates before 1970, and I think probably after 2038 too, I found the Date::Calc module, which is happier with a wider range of dates (back to 1 AD). Here's my modified program. The only sacrifice using this module is that you must extract the year, month and day yourself from the date string. This is trivial in Perl however, using regular expressions (there are other methods too, but I like perl RE's so much I never miss a chance to use them).
Code:
#!/usr/bin/perl

use strict;
use warnings;

use Date::Calc qw(Day_of_Week Day_of_Week_Abbreviation);

foreach (qw(20071021 20060101 19700101 19000101 18000101 01000101)) {
        if (/^(\d\d\d\d)(\d\d)(\d\d)$/) {
                my $dow = Day_of_Week($1, $2, $3);
                my $dayname = Day_of_Week_Abbreviation($dow);
                printf("date=%s, dow=%s, day name=%s\n", $_, $dow, $dayname);
        }
        else {
                warn "expected YYYYMMDD format, got: $_";
        }
}
The output looks like this:
Code:
date=20071021, dow=7, day name=Sun
date=20060101, dow=7, day name=Sun
date=19700101, dow=4, day name=Thu
date=19000101, dow=1, day name=Mon
date=18000101, dow=3, day name=Wed
date=01000101, dow=5, day name=Fri
...use the numeric day of week if you prefer it, or the day name as you see fit.
 
Old 10-21-2007, 12:19 PM   #9
BlueNotes
LQ Newbie
 
Registered: Oct 2007
Posts: 6

Original Poster
Rep: Reputation: 0
I appreciate all the help guys, but the script must be in a bash shell. I was thinking about doing something with the calender such as;
cal $month $year | cut -c 1-2, which will single out "Sun" over the dates bellow it. I'm not sure how accurate it would be though because if I do something like this; cal 06 1984 | cut -c 1-2 | grep 1. it will display the 10 and 17th. I think this method would also require much mode code than I already have.

Hope you guys understand what I'm saying above, and remember that the script must be in a bash shell environment.
 
Old 10-21-2007, 09:09 PM   #10
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Quote:
Hope you guys understand what I'm saying above, and remember that the script must be in a bash shell environment.
Why must it be in bash?
 
Old 10-21-2007, 09:18 PM   #11
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by matthewg42 View Post
Why must it be in bash?
few possibilities
1) OP only knows bash and doesn't want to use anything else
2) doing assignments/homework where its usually under some restrictions
3) system only has bash ??
4) etc etc
 
Old 10-21-2007, 09:37 PM   #12
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Quote:
Originally Posted by ghostdog74 View Post
few possibilities
1) OP only knows bash and doesn't want to use anything else
2) doing assignments/homework where its usually under some restrictions
3) system only has bash ??
4) etc etc
Yes I know, and I want to know which one.
Code:
case $reason in
1)
    echo "/weird/, but whatever floats your boat..."
    ;;
2)
    echo "Then I don't want to be too detailed."
    echo "Yes, this is what I was asking really."
    ;;
3)
    echo "Unlikely."
    echo "Embedded systems would have a smaller shell."
    echo "Other system would probably have at least perl."
    ;;
*)
    echo "So let's hear it."
    ;;
esac
 
Old 10-21-2007, 11:07 PM   #13
BlueNotes
LQ Newbie
 
Registered: Oct 2007
Posts: 6

Original Poster
Rep: Reputation: 0
LOL, Case 2 is correct. At this point it would just be for future knowledge since I already submitted the assignment which was due before 11:59pm yesterday.
I'm still curious though.
 
Old 10-22-2007, 12:22 AM   #14
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Well, you could write your own date functions - perhaps there exists on the net a bunch of shell functions for this purpose which you can copy-paste. It's a bit of a pain in the backside though if you want to do it properly - handling localized versions of day names and so on. The western calendar is not so simple either as you go back - there are different calendars, skipped days and so on.

If you can write a library of bash functions for handling dates efficiently inside bash, I'm sure there would be a lot of interest - it is a very frequently asked "howto" question.

Incidentally, zsh has a pre-written module for sort of thing. zsh has a lot of nice extras like this. The only problem is that you can get addicted to them, and one day you need to work on a machine where you cannot use zsh and it feels like walking in sand.
 
Old 10-22-2007, 10:50 AM   #15
MensaWater
LQ Guru
 
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, CoreOS, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 7,831
Blog Entries: 15

Rep: Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669Reputation: 1669
I actually wrote a shell script once for a co-worker who didn't want to use Perl that did all its date calculations by using the "cal" command (and of course date to get today's date). Not pretty but functional.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: The birth of a new conglomerate LXer Syndicated Linux News 0 11-22-2006 01:54 AM
Wierdest animal ever?? White Spiral General 7 09-21-2005 12:56 AM
sign on invisible in gaim - NOT invi after sign on saravkrish Linux - Software 7 09-12-2005 10:55 PM
Any idea where I can get animal noises in MP3 format? davee General 5 01-20-2005 08:46 AM
separated at birth The Bad Penny General 1 11-10-2004 09:12 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:14 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration