Datums per week ?
Ik ben bezig met een systeem, waarbij je uren per project kunt invullen (hoe lang je eraan gewerkt hebt).
Het ziet er als volgt uit:
Is er een manier om hierbij neer te zetten om welke data het gaat?
Dus bijvoorbeeld week 1 = 1 tm 7 januari (voorbeeldje).
Dan kan je deze functie er op los laten.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
function MondayOfWeek($year, $week) {
// add 0 weeks for week no. 1, add 1 week for week no. 2 etc.
$weeks_to_add = $week - 1;
// get a UTC timestamp for week $week of year $year at 0:00 GMT+0
$gm_unix_timestamp = strtotime("$year-01-04 UTC $weeks_to_add weeks");
// adjust to monday
$weekday = gmstrftime('%u', $gm_unix_timestamp);
$gm_unix_timestamp = strtotime('- ' . ($weekday - 1) . ' days', $gm_unix_timestamp);
return $gm_unix_timestamp;
}
?>
function MondayOfWeek($year, $week) {
// add 0 weeks for week no. 1, add 1 week for week no. 2 etc.
$weeks_to_add = $week - 1;
// get a UTC timestamp for week $week of year $year at 0:00 GMT+0
$gm_unix_timestamp = strtotime("$year-01-04 UTC $weeks_to_add weeks");
// adjust to monday
$weekday = gmstrftime('%u', $gm_unix_timestamp);
$gm_unix_timestamp = strtotime('- ' . ($weekday - 1) . ' days', $gm_unix_timestamp);
return $gm_unix_timestamp;
}
?>
Bron
Vervolgens heb je dus een timestamp van de maandag en kan je alles uitrekenen wat je wilt. Bijvoorbeeld:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// Welke periode zitten we in
$week = date('W');
$jaar = date('Y');
// Zijn het jaar en de week per $_GET meegegeven?
if(isset($_GET['jaar']) && is_numeric($_GET['jaar']) && $_GET['jaar'] > 0) $jaar = $_GET['jaar'];
if(isset($_GET['week']) && is_numeric($_GET['week']) && $_GET['week'] > 0) $week = $_GET['week'];
$start = MondayOfWeek($jaar, $week);
$eind = strtotime("+6 day", $start);
$startDatum = date('d-m-Y',$start);
$eindDatum = date('d-m-Y',$eind);
?>
// Welke periode zitten we in
$week = date('W');
$jaar = date('Y');
// Zijn het jaar en de week per $_GET meegegeven?
if(isset($_GET['jaar']) && is_numeric($_GET['jaar']) && $_GET['jaar'] > 0) $jaar = $_GET['jaar'];
if(isset($_GET['week']) && is_numeric($_GET['week']) && $_GET['week'] > 0) $week = $_GET['week'];
$start = MondayOfWeek($jaar, $week);
$eind = strtotime("+6 day", $start);
$startDatum = date('d-m-Y',$start);
$eindDatum = date('d-m-Y',$eind);
?>
Het is een manier en hij werkt. Zal wellicht nog wel een betere manier zijn.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$weeknr = 3 ;
$jaar = date('Y') ;
$sql = "SELECT '".$jaar."-01-01' + INTERVAL (".$weeknr."-1) WEEK AS eerste_dag,('".$jaar."-01-01' + INTERVAL ".$weeknr." WEEK) - INTERVAL 1 DAY AS laatste_dag";
$result = mysql_query($sql);
if($result && mysql_num_rows($result) == 1)
{
$rij = mysql_fetch_assoc($result) ;
echo 'Week : '.$weeknr.'<br />.' ;
echo 'Eerste dag : '.$rij['eerste_dag'].'<br />.' ;
echo 'Laatste dag : '.$rij['laatste_dag'] ;
}
?>
$weeknr = 3 ;
$jaar = date('Y') ;
$sql = "SELECT '".$jaar."-01-01' + INTERVAL (".$weeknr."-1) WEEK AS eerste_dag,('".$jaar."-01-01' + INTERVAL ".$weeknr." WEEK) - INTERVAL 1 DAY AS laatste_dag";
$result = mysql_query($sql);
if($result && mysql_num_rows($result) == 1)
{
$rij = mysql_fetch_assoc($result) ;
echo 'Week : '.$weeknr.'<br />.' ;
echo 'Eerste dag : '.$rij['eerste_dag'].'<br />.' ;
echo 'Laatste dag : '.$rij['laatste_dag'] ;
}
?>
Iets van deze strekking?
De week met de datum 1-1 is niet per definitie de eerste week van het jaar volgens de ISO-standaard. De week van 4 januari wel.
Bron
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Herco BV Urensysteem</title>
<link href="css/admin.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id='top'>
<div id='top_left'><img src='images/logo.jpg' alt='Herco BV Urensysteem' /></div>
<div id='top_right'</div>
<div style="clear:both; background:none;"></div>
</div>
<div id='content'>
<div id='menu'>
<ul>
</ul>
</div>
<div id='c_right'>
<div class="setup">
<form name="Uren" method="get">
Jaar:
<select name="yr"
OnChange="location.href=yr.options[selectedIndex].name">
<option name="uren.php">Kies een jaar</option>
<option
Code (php)
<option
Code (php)
<option
Code (php)
</select>
Week:
Project:
<select name="prj">
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$sql1 = "SELECT
*
FROM
_projecten
WHERE
project_status = 0";
$sql1_result = mysql_query($sql1);
while ($project = mysql_fetch_assoc($sql1_result))
{
echo "<option value='".$project['project_id']."'";
if(isset($_GET['prj']) && $_GET['prj'] == $project['project_id']) { echo " selected='selected'"; };
echo ">";
echo ucwords($project['project_naam'])."</option>";
}
?>
$sql1 = "SELECT
*
FROM
_projecten
WHERE
project_status = 0";
$sql1_result = mysql_query($sql1);
while ($project = mysql_fetch_assoc($sql1_result))
{
echo "<option value='".$project['project_id']."'";
if(isset($_GET['prj']) && $_GET['prj'] == $project['project_id']) { echo " selected='selected'"; };
echo ">";
echo ucwords($project['project_naam'])."</option>";
}
?>
</select>
<input type="submit" value="Ga" />
</form>
</div>
<p>Hier kun je het aantal uur per week invullen bij projecten waar je aan werkt.</p>
</div>
<div style="clear:both; background:none;"></div>
</div>
</body>
</html>
Mijn database ziet er zo uit:
Quote:
Daar gaat het al niet helemaal goed. Het is overbodig en zeer omslachtig om voor elke aparte dag een aparte kolom aan te maken en bovendien is het fout als je naar de normalisatie regels kijkt.Mijn database ziet er zo uit:
Het enige dat je nodig hebt is een datum veld waarin je datum van de betreffende (werk)dag opslaat en een veld waarin je het aantal gewerkte uren opslaat. Vanuit het datumveld kun je vervolgens wel bepalen over welke dag van de week of welke week van het jaar het gaat. En andersom kun je tijdens het invoeren een bepaalde dag van een bepaalde week herleiden naar een datum.
Kortom, ga normaliseren (zie link) en zorg dat je met een correct datamodel aan de slag gaat. Dat voorkomt in een later stadium heel wat kopzorgen als je bijvoorbeeld statistiekjes uit zo'n tabel wilt gaan halen...
Ik moet dus 1 veld maken voor datum. Ik heb gekeken, en moet 'm volgens mij zo maken:
Gebruikersnaam (varchar(90))
Projectnaam (varchar(50))
datum (DATE)
tijd (TIME)
Hoe kan ik dan per week, per dag invullen hoeveel uur?
Dus je selecteert (zie code) een week.
Dan krijg je max 7 invulvelden om per dag in te vullen hoeveel uur er gewerkt is. Zie: .
Verder had ik een functie ingebouwd zodat je alleen maar een datum kon kiezen van de weken die GEWEEST zijn / BEZIG zijn.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function Week_Select($i)
{
//stel lege returnvalue in:
$returnvalue = '';
switch ($i)
{
case 2008:
$returnvalue .= '<select name="wk">';
for ($n = 1; $n <= 52; $n++)
{
$returnvalue .= "<option>".$n."</option>";
}
$returnvalue .= '</select>';
break;
case 2009:
$returnvalue .= '<select name="wk">';
$weeknr = date("W");
for ($n = 1; $n <= $weeknr; $n++)
{
$returnvalue .= "<option";
if(isset($_GET['wk']) && $_GET['wk'] == $n) { $returnvalue .= " selected='selected'"; }
$returnvalue .= ">".$n."</option>";
}
$returnvalue .= '</select>';
break;
case 2010:
$returnvalue .= '<select name="wk">';
$returnvalue .= "<option>---</option>";
$returnvalue .= '</select>';
break;
}
//nu de waarde van $returnvalue compleet is geef de waarde terug:
return $returnvalue;
}
{
//stel lege returnvalue in:
$returnvalue = '';
switch ($i)
{
case 2008:
$returnvalue .= '<select name="wk">';
for ($n = 1; $n <= 52; $n++)
{
$returnvalue .= "<option>".$n."</option>";
}
$returnvalue .= '</select>';
break;
case 2009:
$returnvalue .= '<select name="wk">';
$weeknr = date("W");
for ($n = 1; $n <= $weeknr; $n++)
{
$returnvalue .= "<option";
if(isset($_GET['wk']) && $_GET['wk'] == $n) { $returnvalue .= " selected='selected'"; }
$returnvalue .= ">".$n."</option>";
}
$returnvalue .= '</select>';
break;
case 2010:
$returnvalue .= '<select name="wk">';
$returnvalue .= "<option>---</option>";
$returnvalue .= '</select>';
break;
}
//nu de waarde van $returnvalue compleet is geef de waarde terug:
return $returnvalue;
}
Kan dit met deze opzet nog steeds?
Gewijzigd op 01/01/1970 01:00:00 door Roeltje M
iemand?
.
Ik zit alleen een beetje vast met database (zie 2).
Als je namelijk later dezelfde week weer selecteert, moet je kunnen zien wat je eerder hebt ingevuld (dus met sql query en while).
Betreffende code:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
$sql_ma = "INSERT
INTO
_uren
(werknemer, project, datum, uren, status)
VALUES
('".$_SESSION['NAAM']."', '".$_GET['prj']."', '".date('Y-m-d', DagWeek($_GET['wk'], $_GET['yr'], "Monday"))."', '".$_POST['Monday']."', 0)";
mysql_query($sql_ma);
echo "Ok!";
}
?>
<form name="Uren" method="post">
<table cellspacing="0" width="70%">
<tr>
<td class="table_top" width="60%">Status</td>
<td class="table_top">Ma</td>
<td class="table_top">Di</td>
<td class="table_top">Wo</td>
<td class="table_top">Do</td>
<td class="table_top">Vr</td>
<td class="table_top">Za</td>
<td class="table_top">Zo</td>
</tr>
<tr>
<td>Aan/af </td>
<td class="date"><input type="text" name="Monday" /></td>
<td class="date"><input type="text" name="Tuesday" /></td>
<td class="date"><input type="text" name="Wednesday" /></td>
<td class="date"><input type="text" name="Thursday" /></td>
<td class="date"><input type="text" name="Friday" /></td>
<td class="date"><input type="text" name="Saturday" /></td>
<td class="date"><input type="text" name="Sunday" /></td>
</tr>
</table>
<input type="submit" value="Bewerk" />
</form>
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
$sql_ma = "INSERT
INTO
_uren
(werknemer, project, datum, uren, status)
VALUES
('".$_SESSION['NAAM']."', '".$_GET['prj']."', '".date('Y-m-d', DagWeek($_GET['wk'], $_GET['yr'], "Monday"))."', '".$_POST['Monday']."', 0)";
mysql_query($sql_ma);
echo "Ok!";
}
?>
<form name="Uren" method="post">
<table cellspacing="0" width="70%">
<tr>
<td class="table_top" width="60%">Status</td>
<td class="table_top">Ma</td>
<td class="table_top">Di</td>
<td class="table_top">Wo</td>
<td class="table_top">Do</td>
<td class="table_top">Vr</td>
<td class="table_top">Za</td>
<td class="table_top">Zo</td>
</tr>
<tr>
<td>Aan/af </td>
<td class="date"><input type="text" name="Monday" /></td>
<td class="date"><input type="text" name="Tuesday" /></td>
<td class="date"><input type="text" name="Wednesday" /></td>
<td class="date"><input type="text" name="Thursday" /></td>
<td class="date"><input type="text" name="Friday" /></td>
<td class="date"><input type="text" name="Saturday" /></td>
<td class="date"><input type="text" name="Sunday" /></td>
</tr>
</table>
<input type="submit" value="Bewerk" />
</form>
Ik wil dus om de form heen een while lus zetten, die kijkt of de datum te vinden is in database, en deze vervolgens uitleest. Alleen met m'n database kan dat volgens mij alleen door bij elke input een while lus te maken (met WHERE datum = ....).
Hoe zou ik het beter kunnen doen? Volgens mij is het probleem voor de $_POST code dan ook opgelost, want daar moet ik nu ook per dag een query maken.
Gewijzigd op 01/01/1970 01:00:00 door Roeltje M
En project naar project_id
En Datum en Tijd samenvoegen tot 1 kolom: een TIMEDATE (of DATETIME)-kolom. Waarom 2 kolommen gebruiken als het (beter) in 1 kan?
En dan nog even over dat werknemer_naam en werknemer_id.
Pas kwam het ook in mijn administratie voor: een naam veranderde!
Want toen ging er eentje (her)trouwen. Waardoor haar naam dus wijzigde (2e huwelijk, naam van haar eerste (overleden) man verdween dus).
En dus veranderd haar naam volkomen.... maar haar werknemer_id blijft.
Doe je dit niet: dan heb je straks 2x gegevens van 1 persoon.
Dus: nogmaals: dit is geen goed datamodel.
Want je gebruikt je werknemers-namen vaker, maar zo staan ze wel vaker in de database.
Voor je probleem:
sla ook (TIMEDATE-kolom!) op wanneer die melding is toegevoegd/bewerkt.
Zo kan je ook controleren dat men zich niet voor de dag van gisteren heeft afwezig gemeld.
En kan je zien wanneer (welke volgorde) zich heeft aangemeld/afgemeld.
Gewijzigd op 01/01/1970 01:00:00 door Eddy E
Ik heb mijn database nu aangepast (bedankt voor tip met id, eigenlijk wel logisch :P):
.
Het maakt echter niet uit wanneer iemand iets heeft ingevoerd; het wordt namelijk naar iemand toegestuurd die het controleert.
Ik zit nu nog steeds met het probleem dat ik per dag een andere query moet maken, helaas. (of ik zit verkeerd te denken)
Gewijzigd op 01/01/1970 01:00:00 door Roeltje M
iemand?
SELECT
kolom
FROM
tabel
WHERE
DATE_FORMAT(datumtijd_kolom,'%Y-%m-%d') = '2009-02-16'
Of een andere datum.
Dan krijg je de regels uit de tabel waar de datum-kolom als datum de goede datum is... (hmm.. deze moet je drie keer lezen om goed te snappen).
Zie maar of iemand hier iets aan heeft.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
echo MondayOfWeek (2009, 4);
echo '<br/>';
$date = MondayOfWeek (2011, 15, true);
echo 'year 2011, week 15: '. $date->format('D Y-m-d');
$now = date_create('now');
echo '<p> Monday of this week: '.
MondayOfWeek (
$now ->format('Y'),
$now ->format('W')
)
.'</p>';
function MondayOfWeek ($year=0, $week=0, $returnObject=false) {
$now = date_create('now');
$firstJanuary = date_create(
sprintf('%04d-%02d-%02d', $year, 1, 1 )
);
$date = clone $firstJanuary;
$daysToFirstMonday = 8 - $date->format('N');
$daysToFirstMondayString = '+'. $daysToFirstMonday .' days';
if ($daysToFirstMonday > 6) {
$daysToFirstMonday -= 7;
$daysToFirstMondayString = '+'. $daysToFirstMonday .' day';
}
$date->modify(
$daysToFirstMondayString
);
while ((int) $date->format('W') != (int) $week) {
$date->modify(
'+7 days'
);
}
if (empty($returnObject)) {
return $date->format('Y-m-d');
}
else {
return $date;
}
}
?>
echo MondayOfWeek (2009, 4);
echo '<br/>';
$date = MondayOfWeek (2011, 15, true);
echo 'year 2011, week 15: '. $date->format('D Y-m-d');
$now = date_create('now');
echo '<p> Monday of this week: '.
MondayOfWeek (
$now ->format('Y'),
$now ->format('W')
)
.'</p>';
function MondayOfWeek ($year=0, $week=0, $returnObject=false) {
$now = date_create('now');
$firstJanuary = date_create(
sprintf('%04d-%02d-%02d', $year, 1, 1 )
);
$date = clone $firstJanuary;
$daysToFirstMonday = 8 - $date->format('N');
$daysToFirstMondayString = '+'. $daysToFirstMonday .' days';
if ($daysToFirstMonday > 6) {
$daysToFirstMonday -= 7;
$daysToFirstMondayString = '+'. $daysToFirstMonday .' day';
}
$date->modify(
$daysToFirstMondayString
);
while ((int) $date->format('W') != (int) $week) {
$date->modify(
'+7 days'
);
}
if (empty($returnObject)) {
return $date->format('Y-m-d');
}
else {
return $date;
}
}
?>
Waarschijnlijk nog wat aan bijschaving toe. Een bescherming tegen een oneindige while lus en zo.
Gewijzigd op 06/01/2011 21:43:37 door Kris Peeters