mysql-function to count days between 2 dates excluding weekends - mysql

I've searched through many examples , good ones I got :
Count days between two dates, excluding weekends (MySQL only)
How to count date difference excluding weekend and holidays in MySQL
Calculate diffference between 2 dates in SQL, excluding weekend days
but didn't get most promising solution , so that i can use in my mysql-function for quering lakhs of rows.
This one was very new concept , but didn't worked for inputs like #start_date = '2013-08-03' , #end_date = '2013-08-21' Expected ans : 13 , its giving only 12,
SELECT 5 * (DATEDIFF(#end_date, #start_date) DIV 7) + MID('0123444401233334012222340111123400012345001234550', 7 * WEEKDAY(#start_date) + WEEKDAY(#end_date) + 1, 1);
So i'did tried to make it by myself -
Concept :
Input : 1. period_from_date - from date
2. period_to_date - to date
3. days_to_exclude - mapping : S M T W TH F Sat => 2^0 + 2^6
(sat and sun to exclude) ^ ^ ^ ^ ^ ^ ^
0 1 2 3 4 5 6
DELIMITER $$
USE `db_name`$$
DROP FUNCTION IF EXISTS `FUNC_CALC_TOTAL_WEEKDAYS`$$
CREATE DEFINER=`name`#`%` FUNCTION `FUNC_CALC_TOTAL_WEEKDAYS`( period_from_date DATE, period_to_date DATE, days_to_exclude INT ) RETURNS INT(11)
BEGIN
DECLARE period_total_num_days INT DEFAULT 0;
DECLARE period_total_working_days INT DEFAULT 0;
DECLARE period_extra_days INT DEFAULT 0;
DECLARE period_complete_weeks INT DEFAULT 0;
DECLARE extra_days_start_date DATE DEFAULT '0000-00-00';
DECLARE num_days_to_exclude INT DEFAULT 0;
DECLARE start_counter_frm INT DEFAULT 0;
DECLARE end_counter_to INT DEFAULT 6;
DECLARE temp_var INT DEFAULT 0;
# if no day to exclude return date-diff only
IF days_to_exclude = 0 THEN
RETURN DATEDIFF( period_to_date, period_from_date ) + 1 ;
END IF;
# get total no of days to exclude
WHILE start_counter_frm <= end_counter_to DO
SET temp_var = POW(2,start_counter_frm) ;
IF (temp_var & days_to_exclude) = temp_var THEN
SET num_days_to_exclude = num_days_to_exclude + 1;
END IF;
SET start_counter_frm = start_counter_frm + 1;
END WHILE;
# Get period days count
SET period_total_num_days = DATEDIFF( period_to_date, period_from_date ) + 1 ;
SET period_complete_weeks = FLOOR( period_total_num_days /7 );
SET period_extra_days = period_total_num_days - ( period_complete_weeks * 7 );
SET period_total_working_days = period_complete_weeks * (7 - num_days_to_exclude);
SET extra_days_start_date = DATE_SUB(period_to_date,INTERVAL period_extra_days DAY);
# get total working days from the left days
WHILE period_extra_days > 0 DO
SET temp_var = DAYOFWEEK(period_to_date) -1;
IF POW(2,temp_var) & days_to_exclude != POW(2,temp_var) THEN
SET period_total_working_days = period_total_working_days +1;
END IF;
SET period_to_date = DATE_SUB(period_to_date,INTERVAL 1 DAY);
SET period_extra_days = period_extra_days -1;
END WHILE;
RETURN period_total_working_days;
END$$
DELIMITER ;
Please let me know the holes where this would fail.Open to any suggestions and comments.

UPDATED: If you just need a number of weekdays between two dates you can get it like this
CREATE FUNCTION TOTAL_WEEKDAYS(date1 DATE, date2 DATE)
RETURNS INT
RETURN ABS(DATEDIFF(date2, date1)) + 1
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7);
Note: The function will still work if you switch start date1 and end date2 dates.
Sample usage:
SELECT TOTAL_WEEKDAYS('2013-08-03', '2013-08-21') weekdays1,
TOTAL_WEEKDAYS('2013-08-21', '2013-08-03') weekdays2;
Output:
| WEEKDAYS1 | WEEKDAYS2 |
-------------------------
| 13 | 13 |
Here is DBFiddle demo

This query will work fine, all the queries above are not working well. Try this :
SELECT ((DATEDIFF(date2, date1)) -
((WEEK(date2) - WEEK(date1)) * 2) -
(case when weekday(date2) = 6 then 1 else 0 end) -
(case when weekday(date1) = 5 then 1 else 0 end)) as DifD
Test it like this :
SELECT ((DATEDIFF('2014-10-25', '2014-10-15')) -
((WEEK('2014-10-25') - WEEK('2014-10-15')) * 2) -
(case when weekday('2014-10-25') = 6 then 1 else 0 end) -
(case when weekday('2014-10-15') = 5 then 1 else 0 end)) as DifD
The result :
DifD
8

I use this. Means there are no functions so can be used in views:
select
datediff(#dateto, #datefrom) +
datediff(#datefrom,
date_add(#datefrom, INTERVAL
floor(datediff(#dateto, #datefrom) / 7) day)) * 2
- case
when weekday(#dateto) = 6 then 2
when weekday(#dateto) = 5 then 1
when weekday(#dateto) < weekday(#datefrom) then 2
else 0
end;

Had a similar issue, I used PHP to remove the weekends, need to know start day and number of days:
EG SQL:
SELECT DAYOFWEEK(`date1`) AS `startday`, TIMESTAMPDIFF(DAY, `date1`, `date2`) AS `interval` FROM `table`
Then run the result through a PHP function:
function noweekends($startday, $interval) {
//Remove weekends from an interval
$wecount = 0; $tmp = $interval;
while($interval/7 > 1) { $interval-=7; $wecount++; }
if($interval+$startday > 5) $wecount++;
$interval = $tmp-($wecount*2);
return $interval;
}

To exclude only Sunday:
CREATE FUNCTION TOTAL_WEEKDAYS(date1 DATE, date2 DATE)
RETURNS INT
RETURN ABS(DATEDIFF(date2, date1)) + 1
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1);

You can also create triggers to automatically calculate it in another column, and you can specify legal holidays in another table:
CREATE OR REPLACE TRIGGER `vacation_before_insert` BEFORE INSERT ON `vacation` FOR EACH ROW
BEGIN
SET #start_date = NEW.Start_date;
SET #end_date = NEW.End_date;
SET #numofholydays = (IFNULL((SELECT SUM(IF(`Date` BETWEEN NEW.Start_date AND NEW.End_date, 1, 0)) as numofdays FROM free_legal_days),0));
SET #totaldays = DATEDIFF(#end_date , #start_date) + 1;
SET #saturdays = WEEK(DATE_ADD(#end_date, INTERVAL 1 DAY))-WEEK(#start_date);
SET #sundays = WEEK(#end_date) - WEEK(#start_date);
SET NEW.Number_of_days = #totaldays-#saturdays-#sundays-#numofholydays;
END;
CREATE OR REPLACE TRIGGER `vacation_before_update` BEFORE UPDATE ON `vacation` FOR EACH ROW
BEGIN
SET #start_date = NEW.Start_date;
SET #end_date = NEW.End_date;
SET #numofholydays = (IFNULL((SELECT SUM(IF(`Date` BETWEEN NEW.Start_date AND NEW.End_date, 1, 0)) as numofdays FROM free_legal_days),0));
SET #totaldays = DATEDIFF(#end_date , #start_date) + 1;
SET #saturdays = WEEK(DATE_ADD(#end_date, INTERVAL 1 DAY))-WEEK(#start_date);
SET #sundays = WEEK(#end_date) - WEEK(#start_date);
SET NEW.Number_of_days = #totaldays-#saturdays-#sundays-#numofholydays;
END;

Related

Mysql to Informix query

I used following query to retrieve information from a mysql table.
SELECT YEARWEEK(fecha,2) ,CONCAT('Semana ', WEEK(fecha)) as y,count(*) as a
FROM mobile09
WHERE fecha BETWEEN TODAY - 30 AND TODAY GROUP BY 1 ORDER BY 1 ASC
How can I get the same result in a Informix database with same tables?
You're going to have to implement your own week of year function for Informix.
Lucky for you, this has already been done at: IBM Developerworks
CREATE FUNCTION day_one_week_one(yyyy INTEGER)
RETURNING DATE
WITH(NOT VARIANT)
DEFINE jan1 DATE;
LET jan1 = MDY(1, 1, yyyy);
RETURN jan1 + MOD(11 - WEEKDAY(jan1), 7) - 3;
END FUNCTION;
CREATE FUNCTION iso8601_weeknum(dateval DATE DEFAULT TODAY)
RETURNING CHAR(2)
WITH(NOT VARIANT)
DEFINE rv CHAR(8);
DEFINE yyyy CHAR(4);
DEFINE ww CHAR(2);
DEFINE d1w1 DATE;
DEFINE tv DATE;
DEFINE wn INTEGER;
DEFINE yn INTEGER;
-- Calculate year and week number.
LET yn = YEAR(dateval);
LET d1w1 = day_one_week_one(yn);
IF dateval < d1w1 THEN
-- Date is in early January and is in last week of prior year
LET yn = yn - 1;
LET d1w1 = day_one_week_one(yn);
ELSE
LET tv = day_one_week_one(yn + 1);
IF dateval >= tv THEN
-- Date is in late December and is in the first week of next year
LET yn = yn + 1;
LET d1w1 = tv;
END IF;
END IF;
LET wn = TRUNC((dateval - d1w1) / 7) + 1;
-- Calculation complete: yn is year number and wn is week number.
-- Format result.
LET yyyy = yn;
IF wn < 10 THEN
LET ww = "0" || wn;
ELSE
LET ww = wn;
END IF
RETURN ww;
END FUNCTION;
Now you should be able to do
select
year(fecha) || iso8601_weeknum(fecha),
'Semana ' || iso8601_weeknum(fecha) as y,
count(*) as a
from
mobile09
where
fecha between today - 30 and today
group by
1, 2
order by
1 asc;

Error Code: 1582 Incorrect parameter count in the call to native function 'STR_TO_DATE'

i hava a query on mysql, and i like to get the date value.
here's the sql
SELECT DISTINCT pegawai.NIP_BARU, pegawai.NAMA_PEGAWAI, pegawai.KODE_PANGKAT_TERAKHIR,pangkat_golongan.NAMA_PANGKAT, pangkat_golongan.GOLONGAN, pegawai.MASA_KERJA_THN_AKHIR, gaji.MASA_KERJA_GOLONGAN, gaji.NOMINAL_GAJI,CASE PEGAWAI.TMT_GOL
WHEN (pangkat_golongan.JENIS_GOLONGAN = '2') AND pegawai.MASA_KERJA_THN_AKHIR MOD 2 = 0 AND 12 - pegawai.MASA_KERJA_BLN_AKHIR + MONTH(pegawai.TMT_GOL)> 12 THEN 2 + YEAR(pegawai.TMT_GOL)
WHEN (pangkat_golongan.JENIS_GOLONGAN = '1') AND pegawai.MASA_KERJA_THN_AKHIR MOD 2 = 1 AND 12 - pegawai.MASA_KERJA_BLN_AKHIR + MONTH(pegawai.TMT_GOL)> 12 THEN 2 + YEAR(pegawai.TMT_GOL)
WHEN (pangkat_golongan.JENIS_GOLONGAN = '1') AND pegawai.MASA_KERJA_THN_AKHIR MOD 2 = 0 AND 12 - pegawai.MASA_KERJA_BLN_AKHIR + MONTH(pegawai.TMT_GOL)< 12 THEN YEAR(pegawai.TMT_GOL)
WHEN (pangkat_golongan.JENIS_GOLONGAN = '2') AND pegawai.MASA_KERJA_THN_AKHIR MOD 2 = 1 AND 12 - pegawai.MASA_KERJA_BLN_AKHIR + MONTH(pegawai.TMT_GOL)< 12 THEN YEAR(pegawai.TMT_GOL)
ELSE 1 + YEAR(pegawai.TMT_GOL) END AS TAHUN_HITUNG,CASE PEGAWAI.MASA_KERJA_BLN_AKHIR
WHEN (12 -(pegawai.MASA_KERJA_BLN_AKHIR) + MONTH(pegawai.TMT_GOL) > 12)
THEN (12 - (pegawai.MASA_KERJA_BLN_AKHIR) + MONTH(pegawai.TMT_GOL) - 12)
ELSE (12 - (pegawai.MASA_KERJA_BLN_AKHIR) + MONTH(pegawai.TMT_GOL)) END AS BULAN_HITUNG, STR_TO_DATE(TAHUN_HITUNG, BULAN_HITUNG, '01','%Y-%m-%d') AS TMT_HITUNG FROM pegawai, gaji, pangkat_golongan WHERE gaji.KODE_GOLONGAN = pegawai.KODE_PANGKAT_TERAKHIR AND gaji.MASA_KERJA_GOLONGAN = pegawai.MASA_KERJA_THN_AKHIR AND pangkat_golongan.KODE_PANGKAT = pegawai.KODE_PANGKAT_TERAKHIR;
and there's always error on this line
STR_TO_DATE(TAHUN_HITUNG, BULAN_HITUNG, '01','%Y-%m-%d') AS TMT_HITUNG
Error Code: 1582
Incorrect parameter count in the call to native function 'STR_TO_DATE'
As the MySQL documentation states, the STR_TO_DATE function takes only two parameters. MySQL STR_TO_DATE The first parameter should be the string that you want to convert, and the second is the date format. It looks like you have the second and not the first.
Do you mean to concatenate the year, month, and date? Try this:
STR_TO_DATE(concat(TAHUN_HITUNG,'-', BULAN_HITUNG,'-', '01'),'%Y-%m-%d') AS TMT_HITUNG
UPDATE
I made your main query a subquery, and then applied the str_to_date function on the results of the subquery, selecting all of the other columns. You could also add your tahun_hitung and bulan_hitung to the first select list. You can't use aliases for your calculations as column names within the same select statement. That's why you were getting the unknown column error.
select NIP_BARU, NAMA_PEGAWAI, KODE_PANGKAT_TERAKHIR, NAMA_PANGKAT,
GOLONGAN, MASA_KERJA_THN_AKHIR, MASA_KERJA_GOLONGAN, NOMINAL_GAJI,
STR_TO_DATE(concat(TAHUN_HITUNG,'-', BULAN_HITUNG,'-', '01'),'%Y-%m-%d') AS TMT_HITUNG
from (
SELECT DISTINCT pegawai.NIP_BARU, pegawai.NAMA_PEGAWAI, pegawai.KODE_PANGKAT_TERAKHIR,pangkat_golongan.NAMA_PANGKAT, pangkat_golongan.GOLONGAN, pegawai.MASA_KERJA_THN_AKHIR, gaji.MASA_KERJA_GOLONGAN, gaji.NOMINAL_GAJI,CASE PEGAWAI.TMT_GOL
WHEN (pangkat_golongan.JENIS_GOLONGAN = '2') AND pegawai.MASA_KERJA_THN_AKHIR MOD 2 = 0 AND 12 - pegawai.MASA_KERJA_BLN_AKHIR + MONTH(pegawai.TMT_GOL)> 12 THEN 2 + YEAR(pegawai.TMT_GOL)
WHEN (pangkat_golongan.JENIS_GOLONGAN = '1') AND pegawai.MASA_KERJA_THN_AKHIR MOD 2 = 1 AND 12 - pegawai.MASA_KERJA_BLN_AKHIR + MONTH(pegawai.TMT_GOL)> 12 THEN 2 + YEAR(pegawai.TMT_GOL)
WHEN (pangkat_golongan.JENIS_GOLONGAN = '1') AND pegawai.MASA_KERJA_THN_AKHIR MOD 2 = 0 AND 12 - pegawai.MASA_KERJA_BLN_AKHIR + MONTH(pegawai.TMT_GOL)< 12 THEN YEAR(pegawai.TMT_GOL)
WHEN (pangkat_golongan.JENIS_GOLONGAN = '2') AND pegawai.MASA_KERJA_THN_AKHIR MOD 2 = 1 AND 12 - pegawai.MASA_KERJA_BLN_AKHIR + MONTH(pegawai.TMT_GOL)< 12 THEN YEAR(pegawai.TMT_GOL)
ELSE 1 + YEAR(pegawai.TMT_GOL) END AS TAHUN_HITUNG,CASE PEGAWAI.MASA_KERJA_BLN_AKHIR
WHEN (12 -(pegawai.MASA_KERJA_BLN_AKHIR) + MONTH(pegawai.TMT_GOL) > 12)
THEN (12 - (pegawai.MASA_KERJA_BLN_AKHIR) + MONTH(pegawai.TMT_GOL) - 12)
ELSE (12 - (pegawai.MASA_KERJA_BLN_AKHIR) + MONTH(pegawai.TMT_GOL)) END AS BULAN_HITUNG
FROM pegawai, gaji, pangkat_golongan
WHERE gaji.KODE_GOLONGAN = pegawai.KODE_PANGKAT_TERAKHIR AND gaji.MASA_KERJA_GOLONGAN = pegawai.MASA_KERJA_THN_AKHIR AND pangkat_golongan.KODE_PANGKAT = pegawai.KODE_PANGKAT_TERAKHIR
) subquery;
You pass 4 params here:
STR_TO_DATE(TAHUN_HITUNG, BULAN_HITUNG, '01','%Y-%m-%d')
mysql doc here

Sum until value reached zero

I have two queries.
The result of the first one is the OnHand quantity of the part in the warehouse:
PartNum OnHandQty IUM
100009 19430.00 KG
The result of the second query are transactions related to the receipts of the goods to the warehouse:
TranDate PartNum TranQty UM Dayss
2014-09-01 100009 10720.000 KG 2
2014-09-01 100009 1340.000 KG 2
2014-08-11 100009 8710.000 KG 23
2014-08-11 100009 3350.000 KG 23
2014-06-30 100009 9380.000 KG 65
Now I need to calculate OnHandQy - TranQty until it hits zero, e.g.
19430 - 10720 = 8710 --not enough
8710 - 1340 = 7370 --not enough
7370 - 8710 = -1340 --enough
As a result I need to receive a table like below:
PartNum OnHandQty IUM [0-10 Days] [11-20 Days] [over 21 Days]
100009 19430.00 KG 12060 null 8710
Any ideas how to get this result?
One idea is to use the following query.
WITH(TranDate,PartNum,TranQty,UM,Dayss) trans
AS
(
-- Your second query
)
SELECT F.PartNum
,F.OnHandQty
,F.IUM
,SUM(t0to10.TransQty) AS [0-10 Days]
,SUM(t11to20.TransQty) AS [11-20 Days]
,SUM(tover20.TransQty) AS [over 21 Days]
FROM (Your first query) AS F
JOIN trans AS t0to10 ON F.PartNum = t0to10.PartNum
AND t0to10.Dayss BETWEEN 0 AND 10
JOIN trans AS t11to20 ON F.PartNum = t11to20.PartNum
AND t11to20.Dayss BETWEEN 11 AND 20
JOIN trans AS tover20 ON F.PartNum = tover20.PartNum
AND tover20.Dayss >20
GROUP BY F.PartNum,F.OnHandQty,F.IUM
Declared the OnHandQty and using cursor in a while loop will help to sort this out.
CREATE TABLE #OnHand(
PartNum NVARCHAR(100)
,OnHandQty DECIMAL
,IUM NVARCHAR(5)
)
INSERT INTO #OnHand
(PartNum, OnHandQty, IUM)
VALUES
('100009', 19430.00, 'KG')
CREATE TABLE #Trans(
TranDate DATETIME
,PartNum NVARCHAR(100)
,TranQty DECIMAL
,IUM NVARCHAR(5))
INSERT INTO #Trans
(TranDate, PartNum, TranQty, IUM)
VALUES
('2014-09-01', '100009', 10720.000, 'KG')
,('2014-09-01', '100009', 1340.000, 'KG')
,('2014-08-11', '100009', 8710.000, 'KG')
,('2014-08-11', '100009', 3350.000, 'KG')
,('2014-06-30', '100009', 9380.000, 'KG')
DECLARE #OnHand_Running DECIMAL
,#OnHandQty DECIMAL
,#TranQty DECIMAL
,#TranDate DATETIME
,#PartNum NVARCHAR(100)
,#First10Days INT = 0
,#Second10Days INT = 0
,#Third10Days INT = 0
SET #PartNum = '100009';
Set #OnHandQty = (Select OnHandQty
FROM #OnHand
WHERE PartNum = #PartNum)
Set #OnHand_Running = #OnHandQty
DECLARE tran_cursor CURSOR
FOR SELECT T.TranQty, T.TranDate
FROM #Trans T
ORDER BY T.TranDate DESC
OPEN tran_cursor
FETCH NEXT FROM tran_cursor
INTO #TranQty, #TranDate
WHILE (##FETCH_STATUS = 0) AND (#OnHandQty > 0)
BEGIN
IF (#OnHandQty - #TranQty) < 0
BEGIN
PRINT CAST(#OnHandQty AS NVARCHAR(100)) + '-' + CAST(#TranQty AS NVARCHAR(100)) + '=' + CAST(#OnHandQty - #TranQty AS NVARCHAR(100)) + ' --Enough'
END
ELSE
BEGIN
PRINT CAST(#OnHandQty AS NVARCHAR(100)) + '-' + CAST(#TranQty AS NVARCHAR(100)) + '=' + CAST(#OnHandQty - #TranQty AS NVARCHAR(100)) + ' --Not Enough'
END
IF (DATEDIFF(DAY, #TranDate, CURRENT_TIMESTAMP) < 10)
SET #First10Days = #First10Days + #TranQty
IF (DATEDIFF(DAY, #TranDate, CURRENT_TIMESTAMP) BETWEEN 10 AND 20)
SET #Second10Days = #Second10Days + #TranQty
IF (DATEDIFF(DAY, #TranDate, CURRENT_TIMESTAMP) > 20)
SET #Third10Days = #Third10Days + #TranQty
SET #OnHandQty = #OnHandQty - #TranQty
FETCH NEXT FROM tran_cursor
INTO #TranQty, #TranDate
END
SELECT #PartNum, #OnHand_Running, 'KG', #First10Days '[0-10] Days', #Second10Days '[11-20] Days', #Third10Days '[over 21 days]'
CLOSE tran_cursor;
DEALLOCATE tran_cursor;
RETURN

Add 28 to last 2 digit of date and replace the order

I have a number such as this : 840106
I need to do the following :
Change the number to date add - and flip the number : 06-01-84
add 28 to the last 2 digit that the date will be : 06-01-12
84 + 16 = 00 + 12 = 12
number is always changing sometimes it cab be 850617 , but format is always same add - and add 28 last 2 digit.
any ideas how to help me here ?
Here is a sqlite solution:
create table t( c text);
insert into t (c) values(990831);
insert into t (c) values(840106);
insert into t (c) values(800315);
insert into t (c) values(750527);
insert into t (c) values(700923);
insert into t (c) values(620308);
select c, substr(c,5,2) || '-' || substr(c,3,2) || '-' ||
case when (substr(c,1,2) + 28) < 100 then (substr(c,1,2) + 28)
else case when ((substr(c,1,2) + 28) - 100) < 10 then '0' || ((substr(c,1,2) + 28) - 100)
else ((substr(c,1,2) + 28) - 100)
end
end
from t;
For formatting you can use
http://www.w3schools.com/sql/func_date_format.asp
For adding days to the date you should take a look at date_add() function
mysql> SELECT DATE_ADD('1998-01-02', INTERVAL 31 DAY);
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
Assuming date is the name of the column containing your date:
DATE_FORMAT(DATE_ADD(STR_TO_DATE(date, %y%m%d), INTERVAL 28 YEAR), %d-%m-%y);
What this does is first formats the string into a date, then adds 28 years, then converts back to string with the new format.
SQLite is a lot tricker with this, you'll need to use substrings.
substr(date,5) || "-" || substr(date,3,4) || "-" || CAST(CAST(substr(date,1,2) as integer) + 28 - 100) as text
I'm not too experienced with SQLite so the casting may be a bit weird.
Here is a t-sql solution that you can use and migrate to mysql.
declare #myDate as char(8) = '840106';
declare #y as char(2), #m as char(2), #d as char(2);
set #y = LEFT (#myDate, 2);
declare #yi as int = Convert (int, #y);
IF #y between 30 and 99 ----------- pick a cut-off year
SET #yi = (28 - (100-#yi));
SET #y = CONVERT(char, #yi)
set #m = SUBSTRING(#myDate, 3, 2);
set #d = SUBSTRING(#myDate, 5, 2);
SET #myDate = #d + '-' + #m + '-' + #y;
PRINT #myDate;

How to round a SQL time variable?

I have declared a time variable with value 23:59:59. So, I need to round it to 24:00. Have you any idea?
declare #t1 time = '23:59:59'
This is necessary only in the select statement. I know that time cannot be inserted as 24:00.
http://msdn.microsoft.com/en-us/library/bb677243(v=sql.105).aspx
How about:
--setup
declare #t1 time = '23:59:59'
--declare #t1 time = '00:59:59'
--declare #t1 time = '00:59:29'
--declare #t1 time = '00:00:00'
--solution for rounding to nearest hour
declare #temp1 int = datepart(minute, #t1) / 30
set #temp1 = (DATEPART(hour, #t1) % 24) + #temp1
select #t1, cast(#temp1 as nvarchar(2)) + ':00' --not too worried about rpading hours since 1:00 makes sense
--solution for rounding to nearest minute
declare #ss int = datepart(second, #t1)/30
, #mm int = datepart(minute, #t1)
, #hh int = datepart(hour, #t1)
, #oo nchar(2) = N'00' --used for padding
set #hh = (#hh + (#mm / 30) * #ss) % 24
set #mm = (#mm + #ss) % 60
select #t1
, substring(#oo + cast(#hh as nvarchar(2)), case when #hh > 9 then 3 when #hh = 0 then 1 else 2 end, 2) --hours rpaded
+ N':'
+ substring(#oo + cast(#mm as nvarchar(2)), case when #mm > 9 then 3 when #mm = 0 then 1 else 2 end, 2) --minutes rpaded