Formatting epoch time - solaris
I have this command, which I found here:
/usr/bin/truss /usr/bin/date 2>&1 |
nawk -F= '/^time\(\)/ {gsub(/" "/,"",$2);printf "0t%d=Y\n", $2-30*86400}' |
adb
which prints 2014 Jan 11 09:48:54. Does anyone know how to reformat the output to YYYYMMDDHH?
I have to use ksh on Solaris. I can't use perl.
A couple of comments:
the first command:
/usr/bin/truss /usr/bin/date 2>&1 |
nawk -F= '/^time\(\)/ {gsub(/" "/,"",$2);printf "0t%d=Y\n", $2-30*86400}'
might be replaced by the much lighter and simpler
nawk 'BEGIN {printf("0t%d=Y\n",srand()-30*86400)}'`
I'm not sure adb is understanding the 0txx=Y syntax but mdb definitely does.
That said, here is something that should fit your needs:
nawk 'BEGIN {printf("0t%d=Y\n",srand()-30*86400)}' | mdb | nawk '
function m2m(m)
{
if(m=="Jan")return 1
if(m=="Feb")return 2
if(m=="Mar")return 3
if(m=="Apr")return 4
if(m=="May")return 5
if(m=="Jun")return 6
if(m=="Jul")return 7
if(m=="Aug")return 8
if(m=="Sep")return 9
if(m=="Oct")return 10
if(m=="Nov")return 11
if(m=="Dec")return 12
}
{
y=$1
m=$2
d=$3
split($4,t,":")
h=t[1]
min=t[2]
printf("%s%02d%02d%02d%02d\n",y,m2m(m),d,h,min)
}'
Notes:
srand (not to be confused with rand) is returning the previous seed when called.
When no argument is passed, srand is using the "time of the day" as seed.
As srand is initialized internally under Solaris nawk, the first srand() call does return the time of the day, i.e. the number of seconds elapsed since the epoch.
If you want a strictly portable way, you need to run a first srand() call before getting its return value but this is not required under Solaris.
This is portable (i.e. POSIX) unlike using truss.
If you have Solaris 11, the answer is easy, because its ksh is ksh93. The Solaris 11 ksh man page has this info about printf:
A %(date-format)T format can be use to treat an argument as a date/time string
and to format the date/time according to the date-format as defined for the
date(1) command.
The allowable date/time string formats aren't specified in the ksh man page, but are (somewhat) mentioned in the AST tm(3) man page. A wide variety are accepted. In particular, this will do what you want:
$ printf "%(%Y%m%d%H)T\n"
2014021118
$ printf "%(%Y%m%d%H)T\n" now
2014021118
$ printf "%(%Y%m%d%H)T\n" "30 days ago"
2014011218
EDIT: Originally I had formed a response that works nicely on Linux, but not on Solaris. This is much longer now, with the original answer below.
To do this purely in the shell, on Solaris, using only the date function, is possible. Kind of. You would have to create some shell functions as well to help out with the subtraction of days from a given date.
Using the functions below, you could do the following to get the desired results:
$ mydate="$(date '+%Y%m%d')"
$ hours="$(date '+%H')"
$ echo "$(date_subtract "${mydate}" 30)${hours}" | adb
or something like that...
On Solaris, the date command only provides Gregorian dates. This is harder to work with for the purpose of this question, so I created a shell function, gregorian_to_julian which can convert a date in 'YYYYMMDD' format to a Julian date of 'YYYYDDD'.
function gregorian_to_julian {
# "Expecting input as YYYYMMDD."
typeset gregorian_date=$1
typeset _year=$(echo "${gregorian_date}" | cut -c1-4)
typeset _month=$(echo "${gregorian_date}" | cut -c5-6)
typeset _day=$(echo "${gregorian_date}" | cut -c7-8)
typeset days
days[01]=31
days[02]=$(( days[01] + 28 ))
if (( _year % 4 == 0 )) && (( _year % 100 != 0 )) || (( _year % 400 == 0 )); then
days[02]=$(( days[01] + 29 ))
fi
days[03]=$(( 31 + days[02] ))
days[04]=$(( 30 + days[03] ))
days[05]=$(( 31 + days[04] ))
days[06]=$(( 30 + days[05] ))
days[07]=$(( 31 + days[06] ))
days[08]=$(( 31 + days[07] ))
days[09]=$(( 30 + days[08] ))
days[10]=$(( 31 + days[09] ))
days[11]=$(( 30 + days[10] ))
typeset julian_date=0
case "${_month}" in
"01") julian_date=$_day ;;
"02") julian_date=$(( days[01] + _day )) ;;
"03") julian_date=$(( days[02] + _day )) ;;
"04") julian_date=$(( days[03] + _day )) ;;
"05") julian_date=$(( days[04] + _day )) ;;
"06") julian_date=$(( days[05] + _day )) ;;
"07") julian_date=$(( days[06] + _day )) ;;
"08") julian_date=$(( days[07] + _day )) ;;
"09") julian_date=$(( days[08] + _day )) ;;
"10") julian_date=$(( days[09] + _day )) ;;
"11") julian_date=$(( days[10] + _day )) ;;
"12") julian_date=$(( days[11] + _day )) ;;
esac
julian_date="${_year}${julian_date}"
echo "${julian_date}"
}
Understanding that the OP wants the date formatted as a Gregorian date, I created a second function, julian_to_gregorian which converts the Julian date back.
function julian_to_gregorian {
# "Expecting input as YYYYDDD."
#set -x
typeset julian_date=$1
typeset _year="$(echo "${julian_date}" | cut -c1-4)"
typeset _month=""
typeset julian_day="$(echo "${julian_date}" | cut -c5-7)"
typeset -RZ2 _day=0
typeset days
days[01]=31
days[02]=$(( days[01] + 28 ))
if (( _year % 4 == 0 )) && (( _year % 100 != 0 )) || (( _year % 400 == 0 )); then
days[02]=$(( days[01] + 29 ))
fi
days[03]=$(( 31 + days[02] ))
days[04]=$(( 30 + days[03] ))
days[05]=$(( 31 + days[04] ))
days[06]=$(( 30 + days[05] ))
days[07]=$(( 31 + days[06] ))
days[08]=$(( 31 + days[07] ))
days[09]=$(( 30 + days[08] ))
days[10]=$(( 31 + days[09] ))
days[11]=$(( 30 + days[10] ))
if (( days[11] < julian_day )); then _month="12"; _day=$(( julian_day - days[11] ));
elif (( days[10] < julian_day )); then _month="11"; _day=$(( julian_day - days[10] ));
elif (( days[09] < julian_day )); then _month="10"; _day=$(( julian_day - days[09] ));
elif (( days[08] < julian_day )); then _month="09"; _day=$(( julian_day - days[08] ));
elif (( days[07] < julian_day )); then _month="08"; _day=$(( julian_day - days[07] ));
elif (( days[06] < julian_day )); then _month="07"; _day=$(( julian_day - days[06] ));
elif (( days[05] < julian_day )); then _month="06"; _day=$(( julian_day - days[05] ));
elif (( days[04] < julian_day )); then _month="05"; _day=$(( julian_day - days[04] ));
elif (( days[03] < julian_day )); then _month="04"; _day=$(( julian_day - days[03] ));
elif (( days[02] < julian_day )); then _month="03"; _day=$(( julian_day - days[02] ));
elif (( days[01] < julian_day )); then _month="02"; _day=$(( julian_day - days[01] ));
else
_month="01"; _day=${julian_day};
fi
echo "${_year}${_month}${_day}"
}
A third function, date_subtract, takes a Gregorian date, converts it to Julian, does the date math, and converts back to Gregorian.
function date_subtract {
typeset julian_from_date=$(gregorian_to_julian "$1")
typeset number_of_days=$2
typeset julian_year=$(echo "${julian_from_date}" | cut -c1-4)
typeset julian_days=$(echo "${julian_from_date}" | cut -c5-7)
typeset leap_year="FALSE"
if (( julian_days - number_of_days > 0 )); then
(( julian_days -= number_of_days ))
else
(( julian_year -= 1 ))
if (( julian_year % 4 == 0 )) && (( julian_year % 100 != 0 )) || (( julian_year % 400 == 0 )); then
leap_year="TRUE"
fi
if [[ "${leap_year}" == "TRUE" ]]; then
(( julian_days = julian_days + 366 - number_of_days ))
else
(( julian_days = julian_days + 365 - number_of_days ))
fi
fi
typeset gregorian_date=$(julian_to_gregorian "${julian_year}${julian_days}")
echo "${gregorian_date}"
}
EDIT: The following works nicely on Linux. And is much simpler.
If you need the date formatted as YYMMDDHH then that is simple enough, as #FrankH. pointed out in his comment:
date +"%Y%m%d%H"
The trickier part is calculating the date 30 days ago, which seems to be your intent. The date command can take the seconds since the epoch and convert that to a date string. This is done with the -d flag. e.g.
$ date -d #123456789
Thu Nov 29 15:33:09 CST 1973
So, if you need the date for thirty days ago, we can take this principle and do a little math to get the needed value.
Note that date '+%s' gives us seconds since the epoch.
$ date -d #$(( $(date '+%s') - $((60 * 60 * 24 * 30 )) )) '+%Y%m%d%H'
2014011211
If you need to pipe that date string to adb then you can surround the command with $(...).
echo $( date -d #$(( $(date '+%s') - $((60 * 60 * 24 * 30 )) )) '+%Y%m%d%H' ) | adb
Related
Using AWK to select records from file1 with obs.# in file 2
I have these to simple test files: This is fil1, containing records I want to select some from 01 02 07 05 10 20 30 25 This is keepNR, containing the record numbers I want to extract from fil1 1 4 7 What I want are these records from fil1 01 (observation/record # 1) 05 (observation/record # 4) 30 (observation/record # 7) I am a novice to AWK, but I have tried these programs: using this, I can see that the observations are there awk 'FNR==NR {a[$1]; next } { for (elem in a) { print "elem=",elem,"FNR=",FNR,"$1=",$1 }} ' keepNR fil1 I had hoped this would work, but I get more than the 2 records: awk 'FNR==NR {a[$1]; next } { for (elem in a) { if (FNR ~ a[elem]) print elem,FNR,$1; next }} END{ for (elem in a) { print "END:", elem }}' keepNR fil1 1 1 01 1 2 02 1 3 07 1 4 05 1 5 10 1 6 20 1 7 30 1 8 25 I first tried using the == instead of the ~, but then no result ?? as you can see here: gg#gg:~/bin/awktest$ awk 'FNR==NR {a[$1]; next } { for (elem in a) { if (FNR == a[elem]) print elem,FNR,$1; next }} ' keepNR fil1 gg#gg:~/bin/awktest$ I have also tried (FNR - a[elem])==0 with no output So I have 2 questions why does if (FNR ~ a[elem]) work, but if (FNR == a[elem]) does not ? why do I get 8 lines of output, instead of 2 ? If you have a better solution, I would love to see it Kind Regards :)
You don't assign to a[$1] so its value is empty: FNR==NR { a[$1]; next } for (elem in a) sets elem to the keys of a. if (FNR == a[elem]) compares against the value in a[elem]. The value is empty, so there is no match. if (FNR ~ a[elem]) tests if FNR matches the empty regex (//), so it always matches. A simpler method is to test if FNR is a key of a: awk ' FNR==NR { a[$1]; next } FNR in a { print "FNR="FNR, "$1="$1 } ' keepNR fil1 which should output: FNR=1 $1=01 FNR=4 $1=05 FNR=7 $1=30
Is there a simple (possibly obfuscated) math expression for the number of days in a given month?
For use in cases where a standard library is not available. Assume that the month is given as an unsigned integer. I'd be interested in seeing the shortest arithmetic expression that gives the correct answer, allowing or disallowing bitwise operators & masks but not lookup tables. Partial expressions can be saved into a variable for readability to showcase the idea used.
Here's an approach that uses only four simple arithmetic and bitwise ops and a 26-bit constant: int days_in_month(unsigned m) { // 121110 9 8 7 6 5 4 3 2 1 0 return 28 + ((0b11101110111110111011001100u >> m * 2u) & 0b11); } If you also want to handle leap year (no mention of it in the question), you can take a similar approach, at the cost of a few more operations and a 50-bit constant: int days_in_month2(unsigned m, bool ly) { return 28 + ((0b11101110111110111011011111101110111110111011001100u >> (m + 12*ly) * 2u) & 0b11); } If you are willing the pass the leap year in a different way, e.g., setting a bit like month | 16 to indicate leap year, it would be more efficient. I assume you pass the month as 1 to 12, not 0 to 11. Tests and generated asm can be seen on godbolt.
Variation om #BeeOnRope nice answer. #include <stdbool.h> int DaysPerMonth(int Month, bool IsLeapYear) { assert(Month >= 1 && Month <= 12); // 0b11101110111110111011001100u // 3 B B E E C C return (((0x3BBEECCu | (IsLeapYear << 2*2)) >> Month*2) & 3) + 28; } #include <stdio.h> int main() { for (int ly = 0; ly <= 1; ly++) { for (int m = 1; m <= 12; m++) { printf("(%2d %2d), ", m, DaysPerMonth(m,ly)); } puts(""); } return 0; }
Brute force answer in pseudocode for readability: monthlength(month,is_leapyear) := oddmonth = ( month + (month >= 8) ? 1 : 0) % 2 // Or (month ^ (month >> 3))&1 feb_days_offset = (month == 2) ? 2 - is_leapyear : 0 return 30 + oddmonth - feb_days_offset Where month >= 8 can also be implemented with a bitshift since it's just the fourth bit in an unsigned representation, so that oddmonth is (first bit) xor (fourth bit), which can be consisely written as (month ^ (month >> 3))&1 . Similarly, subtracting the feb offset can be thought of as flipping the second bit on febuary, and flipping the first bit during leap year february. single line with no intermediate variables: monthlength(month,isleapyear) := 30 + ( month + (month >= 8 ? 1 : 0)) % 2 - (month==2 ? (2 - isleapyear) : 0) Alternatively, one that uses exclusively bitwise arithmetic and shifts using the tricks discussed above: monthlength(month,leapyear) := 30 ^ (month==2)<<1 ^ (month==2)&leapyear ^ (month^month>>3)&1
unsigned int m, leapyr, y ; //m = month range is 1 to 12 //y = year range is 00 to 99 leapyr = ( ( y & 0x03 ) && 1 ); //0 means leap year and 1 means Non leap year m = 30 + ( ( m & 1 ) ^ ( 1 && ( m & 8 ) ) ) - ( ( !( m & 13 ) ) ) - ( ( !( m & 13 ) ) & leapyr ); My answer is considering year. If you don't want to use assign leapyr variable 0 or 1 as you wish.
Trying to find out how to convert local time into universal time (java), all the answers I found don't seem to work for me
I have this (the code), and the answer (the hour) should be 11.00 The problem is that the answers I am getting are completely wrong; (wed april 10 13:09:04 ), todays date ... Also, i guess it needs the lat and long as well, how must I parse this ? String dateString = 26 + "-" + 4 + "-" + 1926 + " " + 5 + ":00:00 " ; SimpleDateFormat f = new SimpleDateFormat( dateString ); f.setTimeZone(TimeZone.getTimeZone("UTC")); System.out.println( (new Date()) ); String dd = f.format(new Date()); System.out.println( " " ) ;
I've got ; String d = LocalDateTime .parse( "26-04-1926 05:00:00", DateTimeFormatter.ofPattern( "dd-MM-uuuu HH:mm:ss" ) ) .atOffset( ZoneOffset.UTC ) .toString(); System.out.println( d ) ; But the output is '1926-04-26T05:00Z' while the hour should be 11:00 Where did I went wrong? Also, can I get the output (the hour) as an int?
bash script how to change date with hrs format and add missing days with copy of above line
I have csv file with data: "smth","txt","33","01-06-2015 00:00" "smth","txt","33","02-06-2015 09:06" "smth","txt","34","03-06-2015 09:54" "smth","txt","34","04-06-2015 00:09" "smth","txt","33","05-06-2015 00:09" "smth","txt","32","07-06-2015 00:09" "smth","txt","30","08-06-2015 10:26" "smth","txt","31","09-06-2015 12:09" "smth","txt","30","10-06-2015 13:17" it should have 30 lines as 30 days of june. There is missing 06-06-2015 and from 11-30-06-2015. I need to put line after 05-06-2015 with data from this line to 06-06-2015 and add missing data from 11-30 june with same data as 10-06-2015. output csv file format should look like this: smth#txt#33#2015-06-01 field with number 33 is random so it cannot be always 33 update 22-06-2015 some of my csv files have data like: "smth","txt","33","01-06-2015 00:00" "smth","txt","33","02-06-2015 09:06" "smth","txt","34","03-06-2015 09:54" "smth","txt","34","04-06-2015 00:09" "smth","txt","33","05-06-2015 00:09" "smth","txt","32","07-06-2015 00:09" "smth","txt","30","08-06-2015 10:26" "smth","txt","31","09-06-2015 12:09" "smth","txt","30","10-06-2015 13:17" "smth2","txt","33","01-06-2015 00:00" "smth2","txt","33","02-06-2015 09:06" "smth2","txt","34","03-06-2015 09:54" "smth2","txt","34","04-06-2015 00:09" "smth2","txt","33","05-06-2015 00:09" "smth2","txt","32","07-06-2015 00:09" "smth2","txt","30","08-06-2015 10:26" "smth2","txt","31","09-06-2015 12:09" "smth2","txt","30","10-06-2015 13:17" so result should be like: 01-30 06-2015 of "smth" and 01-30 06-2015 of "smth2" below is example (dont look at numbers in column 3, it should work as u made it) smth#txt#33#2015-06-01 smth#txt#33#2015-06-02 smth#txt#33#2015-06-03 smth#txt#33#2015-06-04 smth#txt#33#2015-06-05 smth#txt#33#2015-06-06 smth#txt#33#2015-06-07 smth#txt#33#2015-06-08 smth#txt#33#2015-06-09 smth#txt#33#2015-06-10 smth#txt#33#2015-06-11 smth#txt#33#2015-06-12 smth#txt#33#2015-06-13 smth#txt#33#2015-06-14 smth#txt#33#2015-06-15 smth#txt#33#2015-06-16 smth#txt#33#2015-06-17 smth#txt#33#2015-06-18 smth#txt#33#2015-06-19 smth#txt#33#2015-06-20 smth#txt#33#2015-06-21 smth#txt#33#2015-06-22 smth#txt#33#2015-06-23 smth#txt#33#2015-06-24 smth#txt#33#2015-06-25 smth#txt#33#2015-06-26 smth#txt#33#2015-06-27 smth#txt#33#2015-06-28 smth#txt#33#2015-06-29 smth#txt#33#2015-06-30 smth2#txt#33#2015-06-01 smth2#txt#33#2015-06-02 smth2#txt#33#2015-06-03 smth2#txt#33#2015-06-04 smth2#txt#33#2015-06-05 smth2#txt#33#2015-06-06 smth2#txt#33#2015-06-07 smth2#txt#33#2015-06-08 smth2#txt#33#2015-06-09 smth2#txt#33#2015-06-10 smth2#txt#33#2015-06-11 smth2#txt#33#2015-06-12 smth2#txt#33#2015-06-13 smth2#txt#33#2015-06-14 smth2#txt#33#2015-06-15 smth2#txt#33#2015-06-16 smth2#txt#33#2015-06-17 smth2#txt#33#2015-06-18 smth2#txt#33#2015-06-19 smth2#txt#33#2015-06-20 smth2#txt#33#2015-06-21 smth2#txt#33#2015-06-22 smth2#txt#33#2015-06-23 smth2#txt#33#2015-06-24 smth2#txt#33#2015-06-25 smth2#txt#33#2015-06-26 smth2#txt#33#2015-06-27 smth2#txt#33#2015-06-28 smth2#txt#33#2015-06-29 smth2#txt#33#2015-06-30 pls help me with that, show me path to create bash script makes my life easier :)
Bash solution - too complicated for my taste, I'd reach for a more powerful language like Perl. #!/bin/bash remove_doublequotes () { line=("${line[#]#\"}") line=("${line[#]%\"}") } fix_timestamp () { line[3]=${line[3]:6:4}-${line[3]:3:2}-${line[3]:0:2} } read_next=0 printed=0 # Extract the date from the first line to get the number of days in the month. IFS=, read -a line year=${line[3]:7:4} month=${line[3]:4:2} day=${line[3]:1:2} if [[ $day != 01 ]] ; then echo "First day missing." >&2 exit 1 fi cal=$(echo $(cal "$month" "$year")) last_day=${cal##* } remove_doublequotes fix_timestamp for day in $(seq 1 $last_day) ; do day=$(printf %02d $day) if (( read_next )) ; then if IFS=, read -a line ; then remove_doublequotes fix_timestamp printed=0 else # Fill in the missing day at the month end. line=("${last_line[#]}") fi fi if [[ ${line[3]} == *"-$day" ]] ; then # Current line should be printed. (IFS=#; echo "${line[*]}") read_next=1 last_line=("${line[#]}") printed=1 else # Fake the report. insert=("${last_line[#]}") insert[3]=${insert[3]:0:8}$day (IFS=#; echo "${insert[*]}") read_next=0 # We still have to print the line later. fi done if (( ! printed )) ; then # Input contains extra lines. echo "Line '${line[#]}' not processed" >&2 exit 1 fi
Here's a ruby solution. It does not matter if the first record of your data is the first of the month. require 'date' require 'csv' # store the data in a hash, keyed by date new = {} data = CSV.parse(File.read(ARGV.shift)) data.each do |row| d = DateTime.parse(row[-1]) new[d.to_date] = row end # fill in all the missing dates for this month row = data[0] d = DateTime.parse(row[-1]) date = Date.new(d.year, d.month, 1) while date.month == d.month if new.has_key?(date) row = new[date] else new[date] = row[0..-2] + [date.strftime("%d-%m-%Y %H:%M")] end date += 1 end # print the CSV new.keys.sort.each do |key| puts CSV.generate_line(new[key], :force_quotes=>true) end Run it like: ruby program.rb file.csv outputs "smth","txt","33","01-06-2015 00:00" "smth","txt","33","02-06-2015 09:06" "smth","txt","34","03-06-2015 09:54" "smth","txt","34","04-06-2015 00:09" "smth","txt","33","05-06-2015 00:09" "smth","txt","33","06-06-2015 00:00" "smth","txt","32","07-06-2015 00:09" "smth","txt","30","08-06-2015 10:26" "smth","txt","31","09-06-2015 12:09" "smth","txt","30","10-06-2015 13:17" "smth","txt","30","11-06-2015 00:00" "smth","txt","30","12-06-2015 00:00" "smth","txt","30","13-06-2015 00:00" "smth","txt","30","14-06-2015 00:00" "smth","txt","30","15-06-2015 00:00" "smth","txt","30","16-06-2015 00:00" "smth","txt","30","17-06-2015 00:00" "smth","txt","30","18-06-2015 00:00" "smth","txt","30","19-06-2015 00:00" "smth","txt","30","20-06-2015 00:00" "smth","txt","30","21-06-2015 00:00" "smth","txt","30","22-06-2015 00:00" "smth","txt","30","23-06-2015 00:00" "smth","txt","30","24-06-2015 00:00" "smth","txt","30","25-06-2015 00:00" "smth","txt","30","26-06-2015 00:00" "smth","txt","30","27-06-2015 00:00" "smth","txt","30","28-06-2015 00:00" "smth","txt","30","29-06-2015 00:00" "smth","txt","30","30-06-2015 00:00" A GNU awk version. BEGIN {FS = OFS = ","} { datetime = gensub(/^"|"$/, "", "g", $NF) split(datetime, a, /[- :]/) day = mktime( a[3] " " a[2] " " a[1] " 0 0 0" ) data[day] = $0 } NR == 1 { month = strftime("%m", day) year = strftime("%Y", day) row = $0 } END { mday = 1 while ( (day = mktime(year " " month " " mday++ " 0 0 0")) && strftime("%m", day) == month ) { if (day in data) { $0 = row = data[day] } else { $0 = row $NF = strftime("\"%d-%m-%Y %H:%M\"", day) } print } }
Formatting Formulas by Code?
I have the following formula as the grouping for a Cross Tab Report: {Command.Year} & ' ' & {Command.RF Period} Year is a SmallInt and Period is a TinyInt. The problem is that it shows on the report as: 2,009.00 9.00 The database values are actually: 2009 9 I can't remove the decimal places via formatting because they are in the formula together. Ultimately I'd like it to be: 2009 09 Edit: I found this link: http://www.kenhamady.com/form15.shtml Now my code looks like this for period: WhileReadingRecords; StringVar text := Totext ( {Command.RF Period} , 6 , "" ) ; //put your numeric field in this line NumberVar end := length ( text ) ; NumberVar clip := (if Val ( text [ end - 6 to end ] ) = 0 then 1 else 0 ) + (if Val ( text [ end - 5 to end ] ) = 0 then 1 else 0 ) + (if Val ( text [ end - 4 to end ] ) = 0 then 1 else 0 ) + (if Val ( text [ end - 3 to end ] ) = 0 then 1 else 0 ) + (if Val ( text [ end - 2 to end ] ) = 0 then 1 else 0 ) + (if Val ( text [ end - 1 to end ] ) = 0 then 1 else 0 ) + (if Val ( text [ end - 0 to end ] ) = 0 then 1 else 0 ) ; text [ 1 to Length ( text ) - clip ] However, I don't use Crystal Language, I use VB. How do I append a 0 in front of the period if it does not begin with a 1? The problem now is that September (9) shows up after October, Nov, and Dec because aphabetically 9 comes after 1. Anybody?
The ToText function is very useful for this kind of thing, no loops required. In Crystal's VB Syntax : Formula = ToText({Command.Year}, 0, "") & " " & ToText({Command.RF Period}, "00") This should work if {Command.Year} and {Command.RF Period} are integers as you describe.